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

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

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

3回答

801閲覧

VBAで取引先コード事にシートを作成したい

kingkamehameha

総合スコア16

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2020/01/27 01:24

編集2020/01/27 06:21

A列のコード数字2桁~6桁を元にシートを分ける。(今回の質問)

シート内の特定のセルから値を取得して、CSV形式で保存する。(最終形)

困っていること

現在のコードだと1回で、終了してしまいます。
A列の取引先コードの数は決まっていません。取引先毎に出力するにはどうすればいいのでしょうか?

現在のシート

|||

取引先CD請求先郵便番号請求先住所1
20010xxx-xxxxxx県xx市
20010xxx-xxxxxx県xx市
20022xxx-xxxxxx県xx市
20022xxx-xxxxxx県xx市
20099xxx-xxxxxx県xx市

VBA

1Option Explicit 2 3Sub cutxlsx() 4 5'xlsxファイルが存在するかの確認 6Dim rs As Boolean 7If OpenFileName1 <> "" Then 8 Workbooks.Open OpenFileName1 9 rs = True 10Else 11 MsgBox "Excelファイルを指定してください。" 12 rs = False 13End If 14 15If rs = True Then 'xlsxを開いていれば処理を進める 16 17'WorkBookを開いてActiveにさせる 18Workbooks(Filename1).Activate 19 20'WorkBookに開いたファイルのSheet1を保存、今後【ws】で呼び出せる 21Dim ws As Worksheet 22Dim wsname As String 23Dim wsnumber As Integer 24Set ws = ActiveSheet '現在のシート 25 26'A列を文字列から数値に置換(エラー回避) 27With Intersect(ActiveSheet.UsedRange, Columns("A")) 28 .NumberFormat = "" 29 .Value = .Value 30End With 31 32'Sheet名の決定 33wsname = "Sheet" 34wsnumber = 2 35 36'Sheetの追加 37 Worksheets.Add(After:=Worksheets(Worksheets.Count)) _ 38 .name = (wsname & wsnumber) 'シート名はFor文で回して被らないようする 39 40'ここからFor文で囲う必要あり 41 42Sheets("Sheet1").Rows(1).Copy 'ヘッダーをコピー 43Sheets(wsname & wsnumber).Rows(1).PasteSpecial (xlPasteAll) 'ヘッダーを貼付 44 45ws.Activate 'Sheet1をActivate 46 47Dim i As Integer 48Dim j As Integer 49Dim r As Integer 50Dim lastRow As Long 51 52r = 2 '結果表示の初期値 53i = 2 '現在の比較行 54 55lastRow = Cells(Rows.Count, "A").End(xlUp).Row 'A列最終行までを取得 56 57For j = 2 To lastRow '注目行を2行目からA列最終行まで 58 59 If ws.Cells(i, "A") = ws.Cells(j, "A") Then 'A列の比較元行の値と注目行の値が同じ 60 61 ws.Rows(j).Copy Sheets(wsname & wsnumber).Rows(r) '注目行を"test"シートの結果 62 r = r + 1 '結果表示行+1 63End If 64 65Next 66wsnumber = wsnumber + 1 'Sheet名+1 67End If 'xlsxファイルの存在確認 68 69End Sub 70

コード修正致しました。しかし、このコードでは10あるうち8行で止まってしまいます。
恐らくElseの分がFor rの方でカウントされてしまうからのようで、どのようにすれば総実行回数を割り出せるのでしょうか?この時、取引先は全てで4つで実験しています。

VBA

1For r = 2 To ws.Cells(Rows.Count, "A").End(xlUp).Row '取引先コードの分だけ処理する 2 3 '取引先CDが同じ場合 4 If ws.Cells(o, "A") = CD.Cells(j, "A") Then '1つ下の行と値が同じ場合 5 ws.Rows(o).Copy Sheets(wsname & wsnumber).Rows(k) '一致した場合コピー 6 o = o + 1 'コピー先がひとつ下がる 7 k = k + 1 8 Else 9 '取引先コードが変わった時 10 wsnumber = wsnumber + 1 'Sheetを1足して作成 11 Worksheets.Add(After:=Worksheets(Worksheets.Count)) _ 12 .name = (wsname & wsnumber) 'Sheetの追加 13 Sheets("Sheet1").Rows(1).Copy 'ヘッダーをコピー 14 Sheets(wsname & wsnumber).Rows(1).PasteSpecial (xlPasteAll) 'ヘッダーを貼付 15 j = j + 1 '取引先コードの分だけループなので、ひとつ下がる 16 k = 2 17 End If

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/01/27 01:54

元のシートにはどのように並んでいるのでしょうか。 また、「1回で終了」というのはどういう意味でしょうか
kingkamehameha

2020/01/27 02:01

元のシート追加致しました。項目名は20行程あるので、割愛して先頭の3行を表示しています。 追加したシートですと、20010のCD分だけ回って終了になります。コード自体がそういった仕様なので、VBAはそれに従っているまでとは分かっているのですが、、、
hatena19

2020/01/27 04:49

取引先CD で昇順に並んでいるのですか。 あるいは、並んでいない場合、昇順に並び替えてもいいですか。
kingkamehameha

2020/01/27 06:20

取引先は全て昇順で並んでいます。
guest

回答3

0

ベストアンサー

以下のように、1件のデータが1行に対応していて、取引先コードごとにシートを作成してまとめたい、ということでしょうか。

取引先コードほげふが
0012020-01-01200
0032020-01-04400
0022020-01-02800
0012020-01-08200

概念的に考えてみました。
しっかりと確認していないので、間違いがあるかもしれません。

確認済み取引先コード = [] ←シート内のどこかを使うか、取引先の数を超える大きさの配列を用意 for (i = 1行目; i != 空行(最終行を超えている); i++) { if ( 確認済み取引先コード に i行A列 の数字が含まれていない ) { k = 1 sheet = シート作成(シート名は取引先コード) for (j = i; j != 空行(最終行を超えている); j++) { if (i行A列 == j行A列) { sheet の k行目 に j行目 のデータを追加 } k++ } 確認済み取引先コード に i行A列 の数字を追加 } }

投稿2020/01/27 02:26

programming

総合スコア476

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kingkamehameha

2020/01/27 06:24

そのような感じで一度組んでみましたが、総実行回数が行数分なので、Elseに回った分だけ行数が減ってしまいます。この場合どうするのがベターでしょうか? 変数 = EndXlup.Rowで数字に直してElseに回った分だけ、変数から-1していくのがいいのでしょうか? 現時点で結構、重たい処理なので悩んでいます。
kingkamehameha

2020/01/27 07:07

有難う御座います。尚且つ、シート1枚毎にCSVに出力するようにしたいと思います。
guest

0

流としてはこんな感じになると思います。
まずは解読してみてください。

ExcelVBA

1Option Explicit 2 3Sub メイン() 4 Dim wb As Workbook 5 Dim sFullPath As String 6 7 '開くファイルを選択してファイルのフルパスを取得 8 sFullPath = Application.GetOpenFilename() 9 'キャンセルされたらプログラムを抜ける 10 If sFullPath = "False" Then Exit Sub 11 'ファイルを開く 12 Set wb = Workbooks.Open(sFullPath) 13 14 CD毎に分けてCSVに保存 wb 15 16 '開いたファイルを閉じる 17 wb.Close False 18End Sub 19 20'CD毎に分けてCSVに保存 21Sub CD毎に分けてCSVに保存(ByRef wbk As Workbook) 22 Dim rngCode As Range 23 Dim c As Range 24 Dim sCode As String 25 Dim ws As Worksheet 26 27 '順次見て行くセル範囲を限定 28 With wbk.Worksheets(1).UsedRange 29 Set rngCode = .resiz(.Rows.Count - 1, 1).Offset(1) 30 End With 31 32 'セル範囲の内の各セルを順次見て行く 33 For Each c In rngCode 34 'Code番号を取得(セルの値を取得) 35 sCode = CStr(c.Value) 36 'シートの存在確認 37 On Error Resume Next 38 Set ws = wbk.Worksheets(sCode) 39 On Error GoTo 0 40 41 'もしなければ、新たに作り結果を出力(あれば何もしない) 42 If ws Is Nothing Then 43 EachElementToCSV sCode, rngCode 44 End If 45 Next 46End Sub 47 48'Codeで抽出しCsv形式で保存 49Sub EachElementToCSV( _ 50 ByVal sCode As String, _ 51 ByRef rngList As Range) 52 Dim wsResult As Worksheet 53 Dim wbk As Workbook 54 55 Set wbk = .Worksheet.Parent 56 With rngList.CurrentRegion 57 '同じコードの抽出先を用意 58 With wbk 59 .Worksheets.Add After:=.Worksheets(.Worksheets.Count) 60 Set wsResult = .Worksheets(.Worksheets.Count) 61 End With 62 63 '同じコードの抽出 64 .AutoFilter 1, sCode 65 '転記先へコピペ 66 .Copy wsResult.Cells(1) 67 End With 68 69 Application.DisplayAlerts = False 70 'CSV形式で保存 71 wbk.SaveAs Replace(wbk.Path, "????", sCode), xlCSV 72End Sub

※Code毎にシートを作成していますが、
大量のシートが出来ることは現実的ではないと思います。
まずは少ないデータ数で動作確認をし、
ステップインで1行づつ実行し、作業の流れを今一度把握してみてください。

投稿2020/01/27 03:44

mattuwan

総合スコア2136

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

コードを拝見するに、ファイルをオープンし、末端までのループ
処理は存在しますが、CDのシートの内容分ループさせてないので
1回分のループで終わるのではないでしょか?
CDのシートに記載されている個数分ループさせ
さらにそのシートを開いて、ループ処理で末端処理まで
させればよいのではないでしょか?

投稿2020/01/27 02:43

nanami12

総合スコア1015

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kingkamehameha

2020/01/27 02:50

仰っている事は、きっと実現したい事と一致するのですがコードが思いつきません。
nanami12

2020/01/27 03:57 編集

単純に考えて下さい。取引先コードを末端までループする大ループの中に その開いたページの中を末端まで処理する小ループ処理を2つ作ればよいだけです。
kingkamehameha

2020/01/27 06:24

そのような感じで組んでみましたが、Elseに回った分だけ処理行が減ってしまいました。
nanami12

2020/01/27 07:27 編集

小ループの処理はできているわけですから、大ループの処理を追加すればよいだけかと またelseにhogehogeの処理が減ったの意味が分かりません。
nanami12

2020/01/27 07:38

>しかし、このコードでは10あるうち8行で止まってしまいます。 >恐らくElseの分がFor rの方でカウントされてしまうからのようで、 >どのようにすれば総実行回数を割り出 >せるのでしょうか?この時、取引先は全てで4つで実験しています。 10こ処理を行わなければならないのに8こでとまっているのであれば グローバルな変数を用意し、行わなければならない回数を保持し フラグ処理で処理が行われたらカウントアップし グローバル宣言した変数に書かれた処理数と一致しているか 確認する処理を追加すればよいだけかと
kingkamehameha

2020/01/28 03:08

全ての行数をカウントしてelseに回った場合だけ、全ての行数からマイナス1とする事で実現出来ました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問