続いて、ファクト取得関数を実装します。
Function XBRLFact(ByVal instanceFilePath As String, Optional ByVal ContextID As String = "", Optional ByVal namespaceURI As String = "", Optional ElementName As String = "") On Error GoTo ErrorHandler Dim inst As TInstance Dim i As Integer Dim result() As Variant Dim selectedFacts() As TFact 'インスタンスを取得する inst = ParseInstanceFile(instanceFilePath) 'インスタンスのファクトから、出力対象のファクトを選択する selectedFacts = FilterFact(inst.Facts, ContextID, namespaceURI, ElementName) '結果を格納する2次元配列の大きさでReDimする。 '該当のデータが見つからなかったら、UBound(facts)でエラーになるため、ErrorHandlerに飛ぶ ReDim result(0 To UBound(selectedFacts), 0 To 6) For i = 0 To UBound(selectedFacts) result(i, 0) = selectedFacts(i).Value result(i, 1) = selectedFacts(i).ElementName result(i, 2) = selectedFacts(i).ElementNamespace result(i, 3) = selectedFacts(i).ContextID result(i, 4) = selectedFacts(i).Nil result(i, 5) = selectedFacts(i).Unit result(i, 6) = selectedFacts(i).Decimals Next XBRLFact = result Exit Function ErrorHandler: Err.Clear XBRLFact = CVErr(xlErrNA) End Function 'ファクトの配列から、対象のファクトを選択する Private Function FilterFact(Facts() As TFact, ContextID As String, namespaceURI As String, ElementName As String) As TFact() Dim i As Integer Dim j As Integer Dim selectedFacts() As TFact For i = LBound(Facts) To UBound(Facts) If (ContextID = "" Or Facts(i).ContextID = ContextID) And _ (namespaceURI = "" Or Facts(i).ElementNamespace = namespaceURI) And _ (ElementName = "" Or Facts(i).ElementName = ElementName) Then ReDim Preserve selectedFacts(0 To j) selectedFacts(UBound(selectedFacts)) = Facts(i) j = j + 1 End If Next FilterFact = selectedFacts End Function
こちらもXBRLの解析が完了しているインスタンスが取得できてしまえば、きわめて簡単です。メンバー変数であるファクトの配列から、条件に合致するファクトを選別し、出力しています。ファクトの配列から条件に合致するファクトだけを選別するため、下請関数FilterFactを作成しました。
なお、この関数をワークシート関数として使う場合、配列数式として入力する必要があります。配列数式として入力するためには、ワークシートの出力範囲のセルを選択して、F2 キーを押し、Ctrl キーと Shift キーを押しながらEnter キーを押します。この数式が配列数式として入力されていない場合、単一の値(1行1列目の値)のみが計算結果として返されます。