PleasanterのGet API仕様(PageSizeはクライアント指定不可、Response.Dataが直接配列、ClassHash等のネスト構造)を公式マニュアルで確認し訂正。 併せてFilter/Sorter条件をシート上の表で指定できる機能をExport/Get共通で追加する設計に更新。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
8.6 KiB
Export/Get方式切替 設計書
背景・目的
現状 Module1.bas はPleasanterの Export API(CSV全件取得)でデータを取得し、CSVパース後にテーブルへ書き込んでいる。これに加えて Get API(api-record-get-multi)でデータを取得する方式を追加し、基本情報シートのセルで方式を切り替えて実行できるようにする。両方式の処理時間を比較できるよう、開始・終了時刻と経過秒数をシートに記録する。
対象件数は200件以下を想定し、ページング処理は考慮しない。
セル配置(基本情報シート)
| セル | 内容 |
|---|---|
| D3 | ステータスメッセージ(「取込処理中...」「取込処理完了」) |
| D4 | 処理開始時刻(Now) |
| D5 | 処理終了時刻(Now) |
| D6 | 経過秒数((D5 - D4) * 86400 の数値) |
| D7 | 取得方式("Export" または "Get"。未入力・それ以外の値は "Export" 扱い) |
Filter・Sorter条件(基本情報シート、Export/Get共通)
Pleasanter APIの ColumnFilterHash / ColumnSorterHash に渡す条件を、基本情報シート上の表で指定できるようにする。Export方式・Get方式の両方で同じ条件を使う。
セル配置
| 表 | 見出し | データ行 |
|---|---|---|
| Filter表 | F2:G2(列名 / 値) | F3以降(列名が空白の行で終了) |
| Sorter表 | H2:I2(列名 / 昇降順) | H3以降(ascまたはdesc。列名が空白の行で終了) |
- Filter表・Sorter表とも、データ行が1件も無ければ該当するHashはAPIリクエストに含めない
- 両方とも0件の場合は
Viewパラメータ自体をリクエストボディに含めない
SetupFilterSorterTables()(新規・セットアップ用Sub)
基本情報シートのF2:G2、H2:I2を見出しとするExcelテーブル(ListObject)を新規作成する。新版着工要因閲覧シートv0.1.xlsm 上で手動実行することを想定したセットアップ専用処理(run() からは呼ばない)。既にテーブルが存在する場合は何もしない。
BuildViewFromSheet() As Object(新規・共通関数)
基本情報シートのFilter表・Sorter表を読み取り、APIリクエストの View に渡す Dictionary を組み立てて返す。Filter表・Sorter表がともに0件の場合は Nothing を返す。
- Filter表の各行から
colFilter.Add 列名, 値でColumnFilterHash用Dictionaryを作る(1件以上ある場合のみ) - Sorter表の各行から
colSorter.Add 列名, 昇降順でColumnSorterHash用Dictionaryを作る(1件以上ある場合のみ) - どちらか一方でもあれば
ViewDictionaryにColumnFilterHash/ColumnSorterHashをそれぞれ追加(無い方は追加しない) exportCSVDataとgetRecordsDataの両方から呼び出し、viewObjがNothingでなければapiBody.Add "View", viewObjする
全体フロー(Sub run())
Sub run()
Call init ' defaultSh, tableId, apiKey, baseURL, fetchMethod(D7の値) をセット
defaultSh.Range("D4").Value = Now
defaultSh.Range("D3").Value = "取込処理中..."
Application.ScreenUpdating = False
Application.Calculation = xlManual
Select Case fetchMethod
Case "Get"
Call runGetFlow
Case Else
Call runExportFlow
End Select
Application.Calculation = xlAutomatic
Application.ScreenUpdating = True
defaultSh.Range("D5").Value = Now
defaultSh.Range("D6").Value = (defaultSh.Range("D5").Value - defaultSh.Range("D4").Value) * 86400
defaultSh.Range("D3").Value = "取込処理完了"
End Sub
init()にfetchMethod = defaultSh.Range("D7").Valueの読み込みを追加する。runExportFlowは既存のexportCSVData→exportCSVDataToSheet呼び出しをそのまま移設したもの(ロジック無変更)。runGetFlowは新規追加のgetRecordsData→getRecordsDataToSheetを呼ぶ。
Export方式(Filter/Sorter対応のため一部変更)
exportCSVDataToSheet / ParseCsv / CollectionToArray は変更しない。
exportCSVData のみ、既存のコメントアウトされた colFilter / view 部分を BuildViewFromSheet() 呼び出しに置き換える。
Dim viewObj As Object
Set viewObj = BuildViewFromSheet()
If Not viewObj Is Nothing Then
apiBody.Add "View", viewObj
End If
(旧来の yearFilter を使ったコメントアウトコードは削除する)
Get方式(新規追加)
getRecordsData(tableId As String) As Collection
Pleasanterの api-record-get-multi を呼び出し、レコード配列(Collection of Dictionary)を返す。
- エンドポイント:
POST {baseURL}/pleasanter/api/items/{tableId}/get - リクエストボディ:
ApiVersion,ApiKey - 取得件数は指定しない。1回のリクエストでの取得上限はサーバー側既定値(
Api.jsonのPageSize、既定200件)であり、クライアント側からPageSizeを指定するパラメータは存在しない。200件以下想定のため既定動作のまま1回のリクエストで取得しきる(Offsetも指定不要) - レスポンス:
res("Response")("Data")を返す(レコードDictionaryの配列。Resultsという入れ子は存在しない) - 既存の
callRestApiをそのまま利用する - Filter/Sorter条件は
BuildViewFromSheet()を呼び出し、viewObjがNothingでなければapiBody.Add "View", viewObjする(Export方式と同じ共通関数を利用)
レコードのフラット化(FlattenRecord(record As Dictionary) As Dictionary)
Pleasanterのget APIレスポンスは、ClassA〜ClassZ などの項目が ClassHash(同様に NumHash, DateHash, DescriptionHash, CheckHash など)という入れ子のDictionaryの中に格納されている。トップレベルキーをそのままヘッダにすると、これらHash系フィールドが展開されずネストしたDictionaryのまま1セルに入ってしまう。
そのため getRecordsDataToSheet に渡す前に、各レコードをフラット化する処理を挟む。
- レコードDictionaryの各キー・値を走査する
- 値が
Dictionaryである場合(ClassHashなど*Hash系フィールド)は、そのキー自体は使わず、中身のキー・値をそのままフラット化後のDictionaryにマージする(例:ClassHash("ClassA")→ フラット化後のClassAキー) - 値が
Dictionaryでない単純値(Title,Body,Status,ResultIdなど)はそのままキー・値を引き継ぐ - 全レコードに対して同じ処理を行う
getRecordsDataToSheet(records As Collection, targetSheet As String)
exportCSVDataToSheet とは完全に独立した新規関数として実装する(既存ロジックへの影響を避けるため共通化しない)。
records.count = 0の場合はメッセージ表示して終了- 各レコードを
FlattenRecordでフラット化する - ヘッダは フラット化後の1件目レコードのキー一覧をそのまま使用(
Title,Body,ClassA,DateAなどPleasanterの内部キー名。日本語ラベルへの変換は行わない) - 各レコード(フラット化後)の値をヘッダ順に2次元配列へ格納
- シート・テーブル(ListObject)の取得/新規作成、ヘッダ設定、
DataBodyRangeのクリアと書き込みはexportCSVDataToSheetと同様の手順を独自に実装する - テーブル名・出力先シートは
targetSheet(=tableId)を共用し、Export方式実行時に作られた既存テーブルを上書きする(方式を切り替えるたびにヘッダ列構成が変わる点は許容する)
変更対象・追加対象まとめ
- 変更:
init()(fetchMethod読み込み追加),Sub run()(分岐フローに書き換え),exportCSVData(View組み立てをBuildViewFromSheet()呼び出しに置き換え) - 追加:
runExportFlow,runGetFlow,getRecordsData,getRecordsDataToSheet,FlattenRecord,BuildViewFromSheet,SetupFilterSorterTables - 無改造:
exportCSVDataToSheet,ParseCsv,CollectionToArray,callRestApi
非対象・考慮しないこと
- 200件を超えるページング処理
- Get方式でのヘッダの日本語ラベル化・Export方式との列対応付け
- Get方式・Export方式のテーブルを別シートに分離すること(同一テーブルを共用する)