SAP S/4HANAやECCなどSAP ERPにおける品目マスタは、全ロジスティクス共通にして最重要マスタのひとつである。しかし、重要かつ頻出のマスタでありながら、その項目を一覧表示する標準機能はごく限られており、不便を感じることが少なくない。
そのため前回の記事では、BAPIを使ったカスタムプログラム(アドオン)開発や、SAPクエリ作成など、品目マスタの一覧および項目一覧を自作する方法を幾つか紹介した。

本記事ではその実践編として、ExcelマクロからBAPIを呼び出し、品目マスタの全項目を一覧表示を実現する方法を紹介する。
本記事で紹介するExcelマクロは、「便利ツールと資料」からダウンロードしてすぐに利用可能である。ぜひ活用し、品目マスタの管理レベルの向上に役立てていただきたい。
品目マスタの全項目を取得するBAPI
BAPI_MATERIAL_GET_ALL
BAPI_MATERIAL_GET_ALL は品目マスタの全項目を取得できるBAPIである。
本マクロでは、このBAPIをExcelマクロ(VBA)から呼び出し、品目マスタの全項目を取得してExcelワークシートに表示する。
以下は BAPI_MATERIAL_GET_ALL のパラメータ一覧である。列「マクロで使用」に「X」とあるパラメータが、本マクロで使用、つまり、入力または出力に使用しているパラメータである。
Parameter パラメータ | Table テーブル | Description 説明 | マクロで使用 |
---|---|---|---|
Import(入力) | |||
COMP_CODE | BAPI0002_1 | 会社コード | X |
DISTR_CHAN | BAPI_MVKE_GA | 流通チャネル | X |
KZRFB_ALL | MTCOM | Indicator: reset buffer for Material_Pre_Fetch | |
LIFO_VALUATION_LEVEL | BAPI_MYMS_GA | LIFO 評価レベル | |
MATERIAL | BAPI_MARA_GA | 品目コード | X |
MATERIAL_LONG | BAPI_MARA_GA | Material Number (40 Characters, Necessary for Technical Reasons) | |
PLANT | BAPI_MARC_GA | プラント | X |
SALESORG | BAPI_MVKE_GA | 販売組織 | X |
STGE_LOC | BAPI_MARD_GA | 保管場所 | |
STGE_TYPE | BAPI_MLGT_GA | 保管域タイプ | |
VAL_AREA | BAPI_MBEW_GA | 評価レベル | X |
VAL_TYPE | BAPI_MBEW_GA | 評価タイプ | |
WHSENUMBER | BAPI_MLGN_GA | 倉庫番号/複合倉庫 | |
Table(出力) | |||
DEMAND_PENALTYDATA | BAPI_PPO_DMND_PENALTY_GA | Material Penalties : Standard Demand Classes Data | |
EXTENSIONOUT | BAPIPAREX | BAPI パラメータ EXTENSIONIN/EXTENSIONOUT の参照構造 | |
INTERNATIONALARTNOS | BAPI_MEAN_GA | 国際商品コード (EAN) | |
MATERIALDESCRIPTION | BAPI_MAKT_GA | 品目テキスト | X |
MATERIALLONGTEXT | BAPI_MLTX_GA | テキスト (長) | |
NFMCHARGEWEIGHTS | /NFM/BAPITVGW | ||
NFMSTRUCTURALWEIGHTS | /NFM/BAPITKGW | ||
TAXCLASSIFICATIONS | BAPI_MLAN_GA | 税データ | |
UNITSOFMEASURE | BAPI_MARM_GA | 数量単位 | |
Export(出力) | |||
CLIENTDATA | BAPI_MARA_GA | 品目データ (クライアントレベル) | X |
FORECASTPARAMETERS | BAPI_MPOP_GA | 需要予測パラメータ | |
IS_MP_CLIENTDATA | /SAPMP/BAPI_MARA | ||
LIFOVALUATIONDATA | BAPI_MYMS_GA | LIFO 関連品目データ | |
MARC_APS_EXTDATA | BAPI_MARC_APS_EXT_GA | Enhancement of MARC for Advance Planning Data | |
MATPLSTADATA | BAPI_MATPLSTA_GA | Matplsta Data | |
PLANNINGDATA | BAPI_MPGD_GA | 品目マスタ/製品グループの変更伝票構造 | |
PLANTDATA | BAPI_MARC_GA | 品目データ (プラントレベル) | X |
PRTDATA | BAPI_MFHM_GA | 品目マスタの生産資源/治工具 (PRT) 項目 | |
SALESDATA | BAPI_MVKE_GA | 販売データ | X |
STORAGELOCATIONDATA | BAPI_MARD_GA | 品目データ (保管場所レベル) | X |
STORAGETYPEDATA | BAPI_MLGT_GA | 保管域タイプデータ | |
VALUATIONDATA | BAPI_MBEW_GA | 評価データ | X |
WAREHOUSENUMBERDATA | BAPI_MLGN_GA | 倉庫番号データ | |
RETURN | BAPIRETURN | リターンパラメータ | X |
Excelマクロ(VBA)実装のポイント
SAPシステムから品目マスタの全項目を取得・表示するためのExcelマクロコードを以下に解説していく。
SAPシステムへのログオン
SAPシステムにログオンするための情報はワークシート「Logon Setting」に設定する。また、SAPシステムにログインするためのVBAコードは標準モジュール「Common」上の関数「SapChkAndLogon」に実装している。
ワークシート「Logon Setting」の設定方法と、関数「SapChkAndLogon」のVBAコードは、以下の記事で作成したものを流用しているので、同記事を参考にしていただきたい。

検索条件(入力パラメータ)の指定
品目マスタの全項目を表示するためのExcelワークシートは「Material」である。このMaterial上には、品目マスタを検索するための条件の入力と、取得できた項目の出力の両方を行う。
検索条件のための入力パラメータは以下を使用する。
- COMP_CODE(会社コード)
- MATERIAL(品目コード) ※入力必須
- PLANT(プラント)
- SALESORG(販売組織)
- DISTR_CHAN(流通チャネル)
- VAL_AREA(評価レベル)

上図のように、品目コードは複数指定可能である。マクロでは「入力項目(固定)」に入力されている値を上から順に読み取り(品目コードは入力必須)、 BAPI_MATERIAL_GET_ALL の入力パラメータにセットして、同BAPIを実行する。
なお、データの最終行は自動判別するようにコーディングしている。
出力項目は動的に編集・表示
BAPI_MATERIAL_GET_ALL を実行すると、取得された品目マスタの各項目は、CLIENTDATA や PLANTDATA などの各出力パラメータに格納される。
たとえば、品目マスタの基本ビューに相当する CLIENTDATA には約180項目が、プラント別データのビューに相当する PLANTDATA には約250項目が含まれている。これら多くの項目の技術名称を、VBAコード内で一つひとつ記述するのは非常に手間がかかり、非効率だ。
このコーディングの効率化を図るため、本マクロでは、BAPI「RPY_TABLE_READ」を用いて、パラメータ内の項目一覧を取得し、Excelの列として動的に出力する方式を採用している。RPY_TABLE_READ は、指定したテーブルに含まれるすべての項目情報を取得できる BAPI である。
RPY_TABLE_READを使用する利点は、項目の技術名称をVBAコードに記述する手間を省けるだけでない。以下のような複数のメリットも得られる。
- テーブルの中にある項目の、技術名称だででなく、日本語(ローカル)名も取得できる。
- 将来、テーブル(この場合は品目マスタ)の項目が追加された場合、それに伴いBAPI_MATERIAL_GET_ALL のパラメータの項目も増えると予想されるが、追加された項目にも動的に対応できる。
- そのため、将来的にマクロの修正を必要としない。
RPY_TABLE_READ は、透過テーブル(実際にデータが格納されているテーブル)の項目情報を取得するための BAPI である。BAPI_MATERIAL_GET_ALL の出力パラメータも実態はテーブル(構造体)であるため、RPY_TABLE_READ を使えば、これら出力パラメータの項目情報を取得できるというわけだ。
本マクロでは、RPY_TABLE_READ によってパラメータに含まれる全ての項目を取得し、Excel ワークシート上の項目見出し列を動的に生成しているため、マクロコードにおいては、出力パラメータの列名は一切コーディングしていない。

なお、RPY_TABLE_READ の具体的な解説や利用方法を紹介した記事は以下。Excelマクロ+RPY_TABLE_READ による、テーブルの項目情報を取得・表示するExcelマクロ(ダウンロード可能)も紹介している。

Excelマクロ(VBA)の実装例
以下は、SAPシステムにログオンし、BAPI_MATERIAL_GET_ALL を呼び出して、品目マスタの全項目を取得するためのExcelマクロ(VBA)のサンプルコードである。このコードを内蔵したExcelファイルは、「便利ツールと資料」にも公開中である。
Option Explicit Private oRFC As Object 'BAPI Private wsMain As Worksheet 'メインのワークシート Private SapLanguage As String 'ログイン中の言語 'ワークシートの行と列の番号 Private ROW_HEADER As Long '見出し行 Private ROW_DATA_START As Long 'データの開始行 Private COL_COMP_CODE As Integer '会社コード Private COL_MATERIAL As Integer '品目コード Private COL_PLANT As Integer 'プラント Private COL_SALESORG As Integer '販売組織 Private COL_DISTR_CHAN As Integer '流通チャネル Private COL_VAL_AREA As Integer '評価レベル Private COL_MESSAGE As Integer 'メッセージ Private COL_MATL_DESC As Integer '品目テキスト 'テーブルの項目情報を格納するユーザタイプ Private Type TABL_FIELDS FIELDNAME As String 'フィールド技術名 FLABEL As String '項目ラベル End Type '**************************************************************************************** ' 処理名 :Exec_BAPI ' 機能 :BAPI:BAPI_MATERIAL_GET_ALLを実行し、品目マスタの全項目の値を取得・表示する ' 返り値 :なし ' 引数 :なし '**************************************************************************************** Public Sub Exec_BAPI() On Error GoTo Err_Exec_BAPI Dim RowLast As Long '最終行 Dim ColLast As Integer '最終列 Dim aCells() As Variant 'ワークシートのセル範囲に対応する配列 Dim CountMaterial As Long '処理件数のカウント Dim aCLIENTDATA() As TABL_FIELDS '一般データ Dim aPLANTDATA() As TABL_FIELDS 'プラントデータ Dim aSALESDATA() As TABL_FIELDS '販売データ Dim aVALUATIONDATA() As TABL_FIELDS '評価データ Dim Material As String '品目コード Dim Plant As String 'プラント Dim SalesOrg As String '販売組織 Dim DistrChan As String '流通チャネル Dim ValArea As String '評価レベル Dim Message As String 'メッセージ Dim ColDataStart As Integer 'データの開始列(品目テキストの右隣り) Dim ColPlant As Integer 'プラントデータの開始列 Dim ColSales As Integer '販売データの開始列 Dim ColValue As Integer '評価データの開始列 Dim Row As Long Dim Col As Integer Dim i As Integer 'SAPログオン状態の確認 If SapChkAndLogon() <> 0 Then Exit Sub 'SAPにログイン中の言語 SapLanguage = Trim(Worksheets("Logon Setting").Range("Language")) '*** テーブルの項目情報を取得するRPY_TABLE_READの宣言 goSapFunction.RemoveAll Set oRFC = goSapFunction.Add("RPY_TABLE_READ") oRFC.Exports("LANGUAGE") = SapLanguage '処理対象のワークシートを変数にセット Set wsMain = ActiveSheet '列番号のセット Call SetColNumber ColDataStart = COL_MATL_DESC + 1 With wsMain '最終セルの位置の取得 RowLast = CLng(.Cells(ROW_DATA_START, 1).SpecialCells(xlLastCell).Row) ColLast = CInt(.Cells(ROW_DATA_START, COL_MESSAGE + 1).SpecialCells(xlLastCell).Column) '*** ワークシートに品目マスタのフィールドを表示するための列を動的に作成する '表示する列とデータ領域の事前消去 .Range(.Cells(ROW_DATA_START, COL_MESSAGE), .Cells(RowLast, COL_MESSAGE + 1)).ClearContents .Range(.Cells(ROW_DATA_START, COL_MESSAGE + 1), .Cells(RowLast, ColLast)).ClearContents .Range(.Cells(ROW_HEADER, COL_MESSAGE + 2), .Cells(RowLast, ColLast)).ClearContents '一般データ列の作成 If RPY_TABLE_READ("BAPI_MARA_GA", aCLIENTDATA) = 0 Then ReDim aCells(0 To 2, 0 To UBound(aCLIENTDATA)) For i = 0 To UBound(aCLIENTDATA) aCells(0, i) = aCLIENTDATA(i).FLABEL aCells(1, i) = "CLIENTDATA" aCells(2, i) = aCLIENTDATA(i).FIELDNAME Next Else Call SapLogoff Exit Sub End If .Range(.Cells(ROW_HEADER, ColDataStart), .Cells(ROW_HEADER + 2, ColDataStart + UBound(aCLIENTDATA))).Value = aCells 'プラントデータ列の作成 If RPY_TABLE_READ("BAPI_MARC_GA", aPLANTDATA) = 0 Then ReDim aCells(0 To 2, 0 To UBound(aPLANTDATA)) For i = 0 To UBound(aPLANTDATA) aCells(0, i) = aPLANTDATA(i).FLABEL aCells(1, i) = "PLANTDATA" aCells(2, i) = aPLANTDATA(i).FIELDNAME Next Else Call SapLogoff Exit Sub End If ColPlant = ColDataStart + UBound(aCLIENTDATA) + 1 .Range(.Cells(ROW_HEADER, ColPlant), .Cells(ROW_HEADER + 2, ColPlant + UBound(aPLANTDATA))).Value = aCells '販売データ列の作成 If RPY_TABLE_READ("BAPI_MVKE_GA", aSALESDATA) = 0 Then ReDim aCells(0 To 2, 0 To UBound(aSALESDATA)) For i = 0 To UBound(aSALESDATA) aCells(0, i) = aSALESDATA(i).FLABEL aCells(1, i) = "SALESDATA" aCells(2, i) = aSALESDATA(i).FIELDNAME Next Else Call SapLogoff Exit Sub End If ColSales = ColPlant + UBound(aPLANTDATA) + 1 .Range(.Cells(ROW_HEADER, ColSales), .Cells(ROW_HEADER + 2, ColSales + UBound(aSALESDATA))).Value = aCells '評価データ列の作成 If RPY_TABLE_READ("BAPI_MBEW_GA", aVALUATIONDATA) = 0 Then ReDim aCells(0 To 2, 0 To UBound(aVALUATIONDATA)) For i = 0 To UBound(aVALUATIONDATA) aCells(0, i) = aVALUATIONDATA(i).FLABEL aCells(1, i) = "VALUATIONDATA" aCells(2, i) = aVALUATIONDATA(i).FIELDNAME Next Else Call SapLogoff Exit Sub End If ColValue = ColSales + UBound(aSALESDATA) + 1 .Range(.Cells(ROW_HEADER, ColValue), .Cells(ROW_HEADER + 2, ColValue + UBound(aVALUATIONDATA))).Value = aCells '*** 品目マスタの全項目を取得するBAPI_MATERIAL_GET_ALLの宣言 goSapFunction.RemoveAll Set oRFC = goSapFunction.Add("BAPI_MATERIAL_GET_ALL") '*** 入力されている品目マスタの行だけ繰り返し処理 For Row = ROW_DATA_START To RowLast '品目コードの取得 Material = Trim(.Cells(Row, COL_MATERIAL)) '品目コードが未入力の時、処理をスキップ If Material = "" Then GoTo ContinueLoop '処理件数をカウント CountMaterial = CountMaterial + 1 '*** Importパラメータ(検索条件)の設定 '品目コード oRFC.Exports("MATERIAL") = Material '会社コード oRFC.Exports("COMP_CODE") = Trim(.Cells(Row, COL_COMP_CODE)) 'プラント Plant = Trim(.Cells(Row, COL_PLANT)) oRFC.Exports("PLANT") = Plant '販売組織 SalesOrg = Trim(.Cells(Row, COL_SALESORG)) oRFC.Exports("SALESORG") = SalesOrg '流通チャネル DistrChan = Trim(.Cells(Row, COL_DISTR_CHAN)) oRFC.Exports("DISTR_CHAN") = DistrChan '評価クラス ValArea = Trim(.Cells(Row, COL_VAL_AREA)) oRFC.Exports("VAL_AREA") = ValArea '*** BAPI_MATERIAL_GET_ALLの実行 If oRFC.Call = False Then 'BAPI実行時エラーの時はエラーメッセージを表示してループを抜ける MsgBox oRFC.Exception, vbExclamation Exit For End If 'メッセージの表示 If oRFC.Tables("RETURN").RowCount > 0 Then Message = oRFC.Tables("RETURN").Value(1, "MESSAGE") For i = 2 To oRFC.Tables("RETURN").RowCount Message = Message & vbLf & oRFC.Tables("RETURN").Value(i, "MESSAGE") Next .Cells(Row, COL_MESSAGE) = Message End If '品目テキストの表示 For i = 1 To oRFC.Tables("MATERIALDESCRIPTION").RowCount 'ログイン中の言語と一致するテキストを表示 If oRFC.Tables("MATERIALDESCRIPTION").Value(i, "LANGU_ISO") = SapLanguage Then .Cells(Row, COL_MATL_DESC) = oRFC.Tables("MATERIALDESCRIPTION").Value(i, "MATL_DESC") Exit For End If Next '*** 一般データの表示 ReDim aCells(0 To 0, 0 To UBound(aCLIENTDATA)) For i = 0 To UBound(aCLIENTDATA) aCells(0, i) = oRFC.Imports("CLIENTDATA").Value(aCLIENTDATA(i).FIELDNAME) Next .Range(.Cells(Row, ColDataStart), .Cells(Row, ColDataStart + UBound(aCLIENTDATA))).Value = aCells '*** プラントデータの表示 If Plant <> "" Then ReDim aCells(0 To 0, 0 To UBound(aPLANTDATA)) For i = 0 To UBound(aPLANTDATA) aCells(0, i) = oRFC.Imports("PLANTDATA").Value(aPLANTDATA(i).FIELDNAME) Next .Range(.Cells(Row, ColPlant), .Cells(Row, ColPlant + UBound(aPLANTDATA))).Value = aCells End If '*** 販売データの表示 If SalesOrg <> "" And DistrChan <> "" Then ReDim aCells(0 To 0, 0 To UBound(aSALESDATA)) For i = 0 To UBound(aSALESDATA) aCells(0, i) = oRFC.Imports("SALESDATA").Value(aSALESDATA(i).FIELDNAME) Next .Range(.Cells(Row, ColSales), .Cells(Row, ColSales + UBound(aSALESDATA))).Value = aCells End If '*** 評価データの表示 ReDim aCells(0 To 0, 0 To UBound(aVALUATIONDATA)) For i = 0 To UBound(aVALUATIONDATA) aCells(0, i) = oRFC.Imports("VALUATIONDATA").Value(aVALUATIONDATA(i).FIELDNAME) Next .Range(.Cells(Row, ColValue), .Cells(Row, ColValue + UBound(aVALUATIONDATA))).Value = aCells ContinueLoop: Next End With 'ログオフ Call SapLogoff '処理終了メッセージの表示 MsgBox "処理完了" & vbLf & "処理件数 = " & CStr(CountMaterial), vbInformation, "品目マスタ全項目表示処理" Exit Sub Err_Exec_BAPI: 'エラー発生時 MsgBox Err.Description, vbCritical End Sub '**************************************************************************************** ' 処理名 :SetColNumber ' 機能 :ワークシートのセル範囲より、ワークシートの列番号をセットする ' 返り値 :なし ' 引数 :なし '**************************************************************************************** Private Sub SetColNumber() ROW_HEADER = wsMain.Range("ROW_HEADER").Row ROW_DATA_START = wsMain.Range("ROW_DATA_START").Row COL_COMP_CODE = wsMain.Range("COMP_CODE").Column COL_MATERIAL = wsMain.Range("MATERIAL").Column COL_PLANT = wsMain.Range("PLANT").Column COL_SALESORG = wsMain.Range("SALESORG").Column COL_DISTR_CHAN = wsMain.Range("DISTR_CHAN").Column COL_VAL_AREA = wsMain.Range("VAL_AREA").Column COL_MESSAGE = wsMain.Range("MESSAGE").Column COL_MATL_DESC = wsMain.Range("MATL_DESC").Column End Sub '**************************************************************************************** ' 処理名 :RPY_TABLE_READ ' 機能 :BAPI:RPY_TABLE_READを実行し、テーブルの項目情報を取得する ' 返り値 :aCells 項目情報を格納するユーザタイプ型の配列 ' 引数 :Table テーブル名 ' aCells 項目情報を格納するユーザタイプ型の配列 '**************************************************************************************** Private Function RPY_TABLE_READ(ByVal Table As String, ByRef aCells() As TABL_FIELDS) As Long On Error GoTo Err_RPY_TABLE_READ Dim CountTable As Integer Dim i As Integer oRFC.Exports("TABLE_NAME") = Table oRFC.Tables("TABL_FIELDS").Rows.RemoveAll If oRFC.Call = False Then MsgBox oRFC.Exception, vbCritical RPY_TABLE_READ = 1 Exit Function End If CountTable = oRFC.Tables("TABL_FIELDS").RowCount ReDim aCells(0 To CountTable - 1) With oRFC.Tables("TABL_FIELDS") 'テーブルのフィールド名と項目ラベルを配列にセットする For i = 1 To CountTable aCells(i - 1).FIELDNAME = .Value(i, "FIELDNAME") 'aCells(i - 1).FLABEL = .Value(i, "SCRTEXT_S") '項目ラベル短 'aCells(i - 1).FLABEL = .Value(i, "SCRTEXT_M") '項目ラベル中 'aCells(i - 1).FLABEL = .Value(i, "SCRTEXT_L") '項目ラベル長 aCells(i - 1).FLABEL = .Value(i, "DDTEXT") '説明テキスト Next End With RPY_TABLE_READ = 0 Exit Function Err_RPY_TABLE_READ: RPY_TABLE_READ = Err.Number MsgBox Err.Description, vbCritical End Function
Excelマクロファイルの動作環境とダウンロード
動作環境
本マクロ(Excelファイル)は、以下の環境で動作可能である。
- Microsoft Excel デスクトップ版 32 or 64ビット
- Web版のExcelは動作対象外
- SAP GUI for Windows 7.70 以上
Microsoft Excel のビット数と SAP GUI for Windows のビット数は同じなければ動作しない。
たとえば、64ビットの Excel を利用中なら、SAP GUI for Windows も64ビット版である必要がある。
SAP GUI for Windows の32ビット版と64版の違いについて解説した記事は以下。

ファイルのダウンロード
マクロを内蔵したExcelファイルは、下のボタンを押下した先のダウンロードページから、ダウンロード可能である。
Excelマクロの実行方法
以下は、「便利ツールと資料」で公開中のExcelマクロを実行する手順である。
- ワークシート「Logon Setting」に、SAPシステムにログインするための情報を編集する。
- SAP GUI for WindowsからSAPシステムにログインできる状態であれば、「AutoLogon=’X’」とするのがおすすめ。
- SAP GUI for WindowsからSAPシステムにログインできる状態であれば、「AutoLogon=’X’」とするのがおすすめ。
- ワークシート「Material」の「入力項目(固定)」欄に、項目を取得したい品目マスタの情報を下図のように入力する。「品目コード」は入力必須である。

- ボタン「品目マスタ全項目値の取得」を押下する。
- BAPI_MATERIAL_GET_ALLが実行され、列「SAPシステムから返されるメッセージ」に実行結果のメッセージと、「出力項目(動的に生成)」に取得された品目マスタの項目値が出力される。
「SAPシステムから返されるメッセージ」には、エラーや警告のメッセージが表示される。まったく問題がなかった場合、SAPシステムからメッセージは返されない。すなわち、メッセージの値は空白となる。
まとめ:品目マスタの項目一覧は自作できる
品目マスタの項目一覧を表示するSAP標準機能は T-CD: MM60くらいしか存在しないため、実現するには自作する必要がある。カスタムプログラム(アドオン)開発は開発リソースを必要とし、SAPクエリはエンドユーザでも作成できるが表示できる項目数に制限があるなど、一長一短だ。
本記事で紹介した Excelマクロ+BAPIは、その中間に位置するソリューションとして選択肢のひとつになり得る。
マクロを内包したExcelファイルは「便利ツールと資料」にて公開中である。このExcelファイルのマクロを拡張し、自分たちの業務や運用に合った形に発展させていくことも可能である。ぜひ活用および参考にしていただきたい。
コメント