ゆゆのExcelVBA覚書-副業から独立-

現役社内SEがExcel VBAを中心に覚書として書いていくブログです。

【MWS API】ASINから最低価格を取得しよう【Excel VBA】

カート価格の取得ができたら、合わせて最低価格も取得してしまいましょう。 www.yumeigunshi.com

最低価格の取得にはGetLowestOfferListingsForASINを使用したいと思います。

MWS APIを使用した最低価格の取得では、出品形態に関わらず、一番低い価格を取得します。

自己発送の出品者しかいなくて、カート価格がない商品も多いです。
ということはFBA出品している競合がいない商品ということなので、
カート価格がとれないからスルーはもったいないです。

しかし、自己発送の出品価格が低すぎるとこちらがカートを取れないので、
カート価格を取得して仕入判断する必要があります。

※MWS APIの接続確認ができていない方はこちらからどうぞ。 www.yumeigunshi.com

ASINから最低価格を取得するコード

前回記事の接続確認をしたファイルに下記を追加してください。
丸コピで動くと思います。
解説はそのあとに書きます。

Excelシート

f:id:yumeigunshi444:20191222131011p:plain
ASIN入力シート
f:id:yumeigunshi444:20191222131043p:plain
Resultシート

VBAコード

「ASIN」シート 実行ボタン押下時イベント

Option Explicit

Const MAX_COLUMNS As Integer = 4    '最大列数

Private Sub BTN_実行_Click()
    Dim xml As Object
    Dim dic As Object
    
    Dim lstRow As Long
    Dim asinRow As Long
    Dim resultRow As Long
    Dim result() As Variant
    Dim asinList As Collection
    
    Dim asin As String
    Dim shohinObj As Object
    Dim itemObj As Object
    Dim wkObj As Object
    Dim i As Integer, j As Integer
    Dim param As String
    Dim wk As Variant
    
    Dim asinSort() As String
    Dim strSort As String
    strSort = "1,10,2,3,4,5,6,7,8,9"
    asinSort = Split(strSort, ",")
    
    '最終行取得
    lstRow = Cells(Rows.Count, 1).End(xlUp).Row
    If lstRow = 1 Then
        MsgBox ("ASINが入力されていません。")
        Exit Sub
    End If
    
    '初期処理
    Set dic = CreateObject("Scripting.Dictionary")
    
    asinRow = 2     '開始行数
    
    'Result配列の宣言
    ReDim result(1 To lstRow - 1, 1 To MAX_COLUMNS)
    
    While asinRow <= lstRow
        Set asinList = New Collection
        With Sheets("ASIN")
            ' ASINを取り出す
            j = 0
            Do While j < 5
                ' 最終行の場合、処理終了
                If asinRow > lstRow Then
                    Exit Do
                End If
                ' 情報をセット
                asin = CStr(.Cells(asinRow, 1).Value)
                If dic.exists(asin) = False Then    '未処理のASINを処理
                    Set wk = New Collection
                    wk.Add asin, "ASIN"
                    wk.Add asinRow - 1, "ROWS"
                    asinList.Add wk, CStr(asinList.Count + 1)
                    
                    '処理済ASINを格納
                    dic.Add asin, asinRow
                    j = j + 1
                End If
                
                '配列初期化
                result(asinRow - 1, 1) = asin   'ASIN
                result(asinRow - 1, 2) = "-"    '価格 + 送料
                result(asinRow - 1, 3) = "-"    '価格
                result(asinRow - 1, 4) = "-"    '送料
                ' 次行へ
                asinRow = asinRow + 1
            Loop
        End With
        
        param = ""
        ' ASINを1つずつ取り出す
        For i = 0 To UBound(asinSort) - 1
            j = 1
            For Each wk In asinList
                If j = CLng(asinSort(i)) Then
                    If j = 1 Then
                        param = "ASINList.ASIN." & j & "=" & wk("ASIN")
                        
                    Else
                        param = param & "&ASINList.ASIN." & j & "=" & wk("ASIN")
                    End If
                    
                    Exit For
                End If
                j = j + 1
            Next
        Next
        
        ' リクエストを作成
        param = MakeParam(param)
    
        Set xml = getXMLPost("https://mws.amazonservices.jp/Products/2011-10-01", param)
        '情報取得
        Call getLowestOfferListingsForASIN(xml, result, asinList)
        
        
        '1秒のウェイト
        Sleep 1000
    Wend
   
    'Resultへセット
    With Sheets("Result")
        'クリア
        resultRow = .Cells(Rows.Count, 1).End(xlUp).Row + 1
        .Range(.Range("A2").Address, .Cells(resultRow, MAX_COLUMNS).Address) = ""
        '貼り付け
        .Range(.Range("A2").Address, .Cells(lstRow, MAX_COLUMNS).Address) = result
    End With
    
    MsgBox "出力完了"
End Sub


'パラメータ作成
Function MakeParam(asinList As String) As String
    Dim param As String
    Dim paramToSign As String
    Dim sellerId As String
    Dim accessKey As String
    Dim seacretKey As String
    Dim endPoint As String
    Dim marketPlaceId As String
    Dim timeStamp As String
    Dim apiVersion As String
    Dim sign As String
    Dim url As String
    
    'パラメータの取得
    With Sheets("MWS")
        sellerId = .Range("B1").Value
        accessKey = .Range("B2").Value
        seacretKey = .Range("B3").Value
    End With
    endPoint = "mws.amazonservices.jp"
    marketPlaceId = "A1VC38T7YXB528"
    timeStamp = Format(CDate(DateAdd("h", -9, Now)), "yyyy-mm-dd") & "T" & Format(CDate(DateAdd("h", -9, Time)), "hh%3AMM%3Ass") & "Z"
    apiVersion = "2011-10-01"
    
    ' リクエストを作成
    param = asinList _
            & "&AWSAccessKeyId=" & accessKey _
            & "&Action=GetLowestOfferListingsForASIN" _
            & "&ItemCondition=New" _
            & "&MarketplaceId=" & marketPlaceId _
            & "&SellerId=" & sellerId _
            & "&SignatureMethod=HmacSHA256" _
            & "&SignatureVersion=2" _
            & "&Timestamp=" & timeStamp _
            & "&Version=" & apiVersion
            
    paramToSign = "POST" & vbLf & endPoint & vbLf & "/Products/2011-10-01" & vbLf & param
    sign = GetSign(seacretKey, paramToSign)
    
    param = param & "&Signature=" & sign

    MakeParam = param
End Function

'結果XMLから最低価格を取得
Sub getLowestOfferListingsForASIN(xml As Object, result() As Variant, asinList As Collection)
    Dim getProObj As Object
    Dim shohinObj As Object
    Dim wkObj As Object
    Dim strAsin As String
    Dim landedPrice As Double
    Dim price As Double
    Dim soryo As Double
    
    Dim resultRow As Long
    Dim wk As Collection
    Dim k As Integer
    
    
    Set getProObj = xml.SelectNodes("GetLowestOfferListingsForASINResponse/GetLowestOfferListingsForASINResult")

    ' 取得したProductオブジェクトを順次取り出し
    For k = 0 To getProObj.length - 1
        '初期化
        strAsin = ""
        landedPrice = 0
        price = 0
        soryo = 0
        
        'ASIN 取得
        For Each wkObj In getProObj(k).Attributes
            If wkObj.Name = "ASIN" Then
                strAsin = wkObj.Value
            End If
        Next wkObj
        
        ' ASINが取得できていれば処理を行う。
        If strAsin <> "" Then
            
            '商品情報
            Set shohinObj = getProObj(k).SelectNodes("Product/LowestOfferListings/LowestOfferListing")
            If shohinObj.length <> 0 Then
                ' 価格 + 送料を取得
                Set wkObj = shohinObj(0).SelectSingleNode("Price/LandedPrice/Amount")
                If Not wkObj Is Nothing Then
                    landedPrice = wkObj.text
                End If
                ' 価格を取得
                Set wkObj = shohinObj(0).SelectSingleNode("Price/ListingPrice/Amount")
                If Not wkObj Is Nothing Then
                    price = wkObj.text
                End If
                ' 送料を取得
                Set wkObj = shohinObj(0).SelectSingleNode("Price/Shipping/Amount")
                If Not wkObj Is Nothing Then
                    soryo = wkObj.text
                End If
            End If
            
            '情報のセット
            With Sheets("Result")
                '行数取得
                Set wk = asinList(CStr(k + 1))
                resultRow = wk("ROWS")
                
                result(resultRow, 2) = Int(landedPrice)
                result(resultRow, 3) = Int(price)
                result(resultRow, 4) = Int(soryo)
            End With
        End If
    Next
   
End Sub

実行結果

f:id:yumeigunshi444:20191222131306p:plain
ASINを入力して「実行」ボタンを押下
f:id:yumeigunshi444:20191222131330p:plain
結果がResultシートに出力される

GetLowestOfferListingsForASINの解説

前回記事であるカート価格取得ととても似ています。

違うところといえば、自己発送の商品は送料を設定していることが多いので、送料も取得する必要があるところくらいでしょうか。

スロットリング

f:id:yumeigunshi444:20191222131832p:plain
スロットリング
1秒ごとに5商品取得できるようになるので、
今回は一度のリクエストで5個のASINを送信します。

リクエストパラメーター

必須パラメーターはMarketplaceIdASINListです。

こちらはカート価格取得と全く同じ。

VBAコード

こちらもカート価格取得とほぼ同じなので、詳しくは前回記事を参照。 www.yumeigunshi.com

取得項目のみ解説していきます。

最低価格の取得

B07CCBRLJRを参考に、スクラッチパッドで結果を表示します。
Amazon.com - Marketplace Web Service

f:id:yumeigunshi444:20191222132657p:plain
スクラッチパッド
今までよりたくさん結果が表示されて困惑されるかもしれませんが、
これは出品者の数だけ価格が表示されているだけです。

今回は最低価格の取得なので、一番最初に出てくる価格のみ取得してしまえばOKです。

それぞれの項目取得するコード
    '商品情報
    Set shohinObj = getProObj(k).SelectNodes("Product/LowestOfferListings/LowestOfferListing")
    If shohinObj.length <> 0 Then
        ' 価格 + 送料を取得
        Set wkObj = shohinObj(0).SelectSingleNode("Price/LandedPrice/Amount")
        If Not wkObj Is Nothing Then
            landedPrice = wkObj.text
        End If
        ' 価格を取得
        Set wkObj = shohinObj(0).SelectSingleNode("Price/ListingPrice/Amount")
        If Not wkObj Is Nothing Then
            price = wkObj.text
        End If
        ' 送料を取得
        Set wkObj = shohinObj(0).SelectSingleNode("Price/Shipping/Amount")
        If Not wkObj Is Nothing Then
            soryo = wkObj.text
        End If
    End If

上記コードで3つの項目が取得できます。

<Price>
          <Price>
            <LandedPrice>
              <CurrencyCode>JPY</CurrencyCode>
              <Amount>8965.00</Amount>
            </LandedPrice>
            <ListingPrice>
              <CurrencyCode>JPY</CurrencyCode>
              <Amount>8345.00</Amount>
            </ListingPrice>
            <Shipping>
              <CurrencyCode>JPY</CurrencyCode>
              <Amount>620.00</Amount>
            </Shipping>
          </Price>

LandedPrice :価格 + 送料
ListingPrice :価格のみ
Shipping:送料
となっています。

カート価格の取得ができた人はもう簡単にできると思います!

補足

実際にAmazonの画面で確認してみましょう。 f:id:yumeigunshi444:20191222134415p:plain 先ほどのテストで使用したB07CCBRLJRの商品です。
Amazonが9513円でカートを取っています。
カート価格を取得する場合は、9513円を取得しますが、
今回の最低価格取得の場合、
一番上に表示されている8345円(送料630円)のデータを取得することになります。

まとめ

カート価格とほぼ同じなので、解説する必要なかったかもしれません。

次回はFBA出品手数料の取得を解説していきたいと思います。
実はこれが一番苦労していまして、ネットにも情報が少なかった・・・

なのでかなり有力な記事になりそうです!
今までの解説記事
www.yumeigunshi.com www.yumeigunshi.com www.yumeigunshi.com