質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.13%

VBAによるカンマ区切り文字列→配列化→整列処理

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 825

score 7

いま、日本郵政の郵送ラベルの自動作成をしたいと思っております。
そのためには、日本郵政のクリックポストというラベル発行サービスがあり、
そのサービスの指定したcsvをuploadしなければならず、それによりはじめてラベルが自動で印刷できる仕組みになっています。
そこで、そのサービスの指定したcsvを作りたいのですが、一つ一つの入力が大変で自動化したいと思っています

そこで、以下のようにしたいと思っています。

1.ECサイト(shopfy)の注文データの氏名住所データをコピー(氏名, 150-0000, 東京都 住所1,住所2,ビル名,日本)
2.これを日本郵政のサービス(クリックポスト)が求めるデフォルトcsvの入力欄外に上記カンマ区切りデータを貼付(以下codeでは10列目)
3.VBAを実行することで、上記カンマ区切りデータを並べ替えして入力欄に貼付

※問題は、注文者によって住所の描き方が違うことです。つまり住所1に全ての住所を記載する人もいれば、住所1に町名迄、住所2にビル名
など丁寧に分けて書く人がいることです。これにより配列の数が変わってきてしまい、以下のcodeではインデックスエラーが起こります。

ショッピファイの注文データが多く、クリックポストのCSVにするのが大変でどなたか助けてもらえませんでしょうか。

また、こちらの質問とは別件ですが、この方法ではショッピファイの注文を一人一人の画面を見て、その注文データの氏名住所をコピーしてと、まだ少し手間がかかるのですが、本当はなにかすれば、一気に未配送のデータをもとにクリックポストのcsvを作り出す良い方法があるように思っています。検索してもあまりでてこず、もしご存知の方がいらっしゃいましたら教えていただけますと本当に助かります。
御忙しい中恐縮です。

Sub clickpostcsv_gen()

    Dim LastRow As Long
        LastRow = Cells(Rows.Count, 10).End(xlUp).Row - 1 
'あるcsvファイルの(2,10)セルにカンマ区切りデータを入力しておりその行数を調べています。LastRowには入力データ数が入ります。

    Dim i As Long, tmp As Variant
    For i = 1 To LastRow
        tmp = Split(Cells(i + 1, 10), ",")

        Cells(i + 1, 2) = tmp(0)  '(,2)が氏名入力欄です。
        Cells(i + 1, 1) = tmp(1〉  '(,1)が郵便番号入力欄です。
        Cells(i + 1, 4) = tmp(2)  '(,4)~(,6)が住所入力欄です。問題はここです。注文データによってはtmp(4)がなくインデックスエラーになるのです。
        Cells(i + 1, 5) = tmp(3)
        Cells(i + 1, 6) = tmp(4)

    Next i
End Sub
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • meg_

    2020/05/02 15:49

    コードは「コードの挿入」で記入してください。

    キャンセル

  • JMS

    2020/05/02 23:29

    ありがとうございます。失礼致しました。修正させていただきました。

    キャンセル

回答 2

checkベストアンサー

+2

"氏名1, 150-0000, 東京都 住所1,住所2,ビル名,日本" のデータが欠ける時に
"氏名2, 150-0001, 東京都 住所1,,,日本" のようにカンマが残されるなら
Splitで分割したときの番号と項目の対応はズレないので、以下のようなやり方で対処できそうです。
もし "氏名3, 150-0001, 東京都 住所1,日本" のように、カンマが無くて
途中が抜ける場合には、分割後に何らかの内容を判断して対応する項目に埋める必要があります。

Sub clickpostcsv_gen()

    Dim LastRow As Long
        LastRow = Cells(Rows.Count, 10).End(xlUp).Row - 1 

    Dim i As Long, tmp As Variant
    Dim columns as Long

    Dim CustomerName as String
    Dim ZipCode as String
    Dim Address1 as String
    Dim Address2 as String
    Dim BuildingName as String
    Dim CountryName as String

    For i = 1 To LastRow
        tmp = Split(Cells(i + 1, 10), ",")
        columns = UBound(tmp)
        CustomerName = ""
        ZipCode = ""
        Address1 = ""
        Address2 = ""
        BuildingName = ""
        CountryName = ""      
        'カラム数が1〜6でない時は
        If columns > 6 Or columns < 1 Then
           GoTo CONTINUE            'その行を飛ばす
           ' BuildingName = "Error"  またはエラーメッセージを出力
        End If
        If columns > 5 Then
           CountryName = tmp(5)
        End If
        If columns > 4 Then
           BuildingName = tmp(4)
        End If
        If columns > 3 Then
           Address2 = tmp(3)
        End If
        If columns > 2 Then
           Address1 = tmp(2)
        End If
        If columns > 1 Then
           ZipCode = tmp(1)
        End If
        If columns > 0 Then
           CustomerName = tmp(0)
        End If

        Cells(i + 1, 1) = ZipCode      'お届け先郵便番号
        Cells(i + 1, 2) = CustomerName 'お届け先氏名
        Cells(i + 1, 3) = "様"         'お届け先敬称
        Cells(i + 1, 4) = Address1     'お届け先住所1行目
        Cells(i + 1, 5) = Address2     'お届け先住所2行目
        Cells(i + 1, 6) = BuildingName 'お届け先住所3行目

CONTINUE:
    Next i
End Sub

Shopifyヘルプによれば、CSVで注文データの一括出力もできるようです。

注文をCSVファイルにエクスポートする
https://help.shopify.com/ja/manual/orders/export-orders

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/05/03 17:15

    正直、感動しました。完璧です。こういう頭の使い方ができるのは何故なんでしょう?天才のように思えます・・・。いやぁすごいです。 If columns > 5 Then こうやってコラム数を計算していってtmp配列の変数への挿入を調整するんですね。考え方がとても勉強になりました。

    キャンセル

+2

配列がインデックスエラーになる対策として
UBound関数で配列の最大値を指定して処理を行うといいと思います。
参考サイト

    dim k as long
    For k = 2 To UBound(tmp)
        Cells(i + 1, k + 2) = tmp(k)       
    Next k

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/05/02 23:31 編集

    ご返信いただき有難うございました。こちらも考えてみたのですが、以下のように、tmp(x)を挿入する先が単純にi+1,k+2とできないので単純なforループで回せないのです。これができればforループを使いたいと思ったのですが。

    ```VBA
    Cells(i + 1, 2) = tmp(0)  '(,2)が氏名入力欄です。
    Cells(i + 1, 1) = tmp(1〉  '(,1)が郵便番号入力欄です。
    Cells(i + 1, 4) = tmp(2)  '(,4)~(,6)が住所入力欄です。問題はここです。注文データによってはtmp(4)がなくインデックスエラーになるのです。
    Cells(i + 1, 5) = tmp(3)
    Cells(i + 1, 6) = tmp(4)
    ```

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る