- ベストアンサー
Excel VBAでシート間データ転記・結合方法
- Excel VBAを使用して、シート1からシート2にデータを転記する方法について説明します。
- 転記方法は、シート1のD列の値をシート2のA列に、シート1のE列の値をシート2のB列に、シート1のF列の値をシート2のC列に、シート1のC列の値が同じ場合はシート2のD列のデータにカンマで結合して転記します。
- また、シート2のE列には、結合したデータの個数を表示します。転記は、Do~LoopかFor~Next文を使用して、上から順に最終行まで処理します。データの重複を判定するために、変数を使用して前回転記した値と比較します。結合したデータの個数は、変数をカウントアップすることで求めることができます。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
No.2・4です。 >Sheet1のD列に途中空白があるのが >わかり苦戦しています・・・ とありますが、最初の質問ではその件がなかったので、当然今までのコードではご希望の動作はしないと思います。 空白なのはD列だけですかね? 仮に行すべてが空白の場合はNo.4のコードでも大丈夫だと思いますが、↓の画像のような感じの場合は D列に一つ上のセルデータを表示させれば大丈夫だと思います。 もう一度コードを載せておきます。 Sub test3() Dim i, j, k As Long Dim str As String Dim ws1, ws2 As Worksheet Set ws1 = Worksheets("sheet1") Set ws2 = Worksheets("sheet2") For i = 3 To ws1.Cells(Rows.Count, 3).End(xlUp).Row If ws1.Cells(i, 4) = "" Then ws1.Cells(i, 4) = ws1.Cells(i - 1, 4) End If Next i ws2.Cells.Clear With ws2.Cells(1, 1) .Value = "品物" .Offset(, 1) = "生産国" .Offset(, 2) = "サイズ" .Offset(, 4) = "個数" End With For i = 3 To ws1.Cells(Rows.Count, 3).End(xlUp).Row If WorksheetFunction.CountIf(ws2.Columns(1), ws1.Cells(i, 4)) = 0 Then With ws2.Cells(Rows.Count, 1).End(xlUp).Offset(1) .Value = ws1.Cells(i, 4) .Offset(, 1) = ws1.Cells(i, 5) .Offset(, 2) = ws1.Cells(i, 6) End With End If Next i For j = 2 To ws2.Cells(Rows.Count, 1).End(xlUp).Row For i = 3 To ws1.Cells(Rows.Count, 3).End(xlUp).Row If ws1.Cells(i, 4) = ws2.Cells(j, 1) Then str = str & ws1.Cells(i, 3) & "," k = k + 1 End If Next i With ws2.Cells(j, 4) .Value = Left(str, Len(str) - 1) .Offset(, 1) = k End With str = "" k = 0 Next j ws2.Columns("A:E").AutoFit End Sub こんなんではどうでしょか? ※ 具体的なデータ配置が判ればもっと詳細なコードが提示できると思います。m(__)m
その他の回答 (4)
- tom04
- ベストアンサー率49% (2537/5117)
No.2です! たびたぼごめんなさい。 前回のコードはSheet1の列が1列ずれていました。 Sheet1のデータはC列の3行目からあるのですよね? No.2は無視して、↓のコードにしてください。 Sub test2() Dim i, j, k As Long Dim str As String Dim ws1, ws2 As Worksheet Set ws1 = Worksheets("sheet1") Set ws2 = Worksheets("sheet2") ws2.Cells.Clear With ws2.Cells(1, 1) .Value = "品物" .Offset(, 1) = "生産国" .Offset(, 2) = "サイズ" .Offset(, 4) = "個数" 'Sheet1の項目名はこちらで勝手に入れています。 '尚、Sheet1のD列の項目名が不明ですので、Sheet2のD1セルは空白にしています。 End With For i = 3 To ws1.Cells(Rows.Count, 3).End(xlUp).Row If WorksheetFunction.CountIf(ws2.Columns(1), ws1.Cells(i, 4)) = 0 Then With ws2.Cells(Rows.Count, 1).End(xlUp).Offset(1) .Value = ws1.Cells(i, 4) .Offset(, 1) = ws1.Cells(i, 5) .Offset(, 2) = ws1.Cells(i, 6) End With End If Next i For j = 2 To ws2.Cells(Rows.Count, 1).End(xlUp).Row For i = 3 To ws1.Cells(Rows.Count, 3).End(xlUp).Row If ws1.Cells(i, 4) = ws2.Cells(j, 1) Then str = str & ws1.Cells(i, 3) & "," k = k + 1 End If Next i With ws2.Cells(j, 4) .Value = Left(str, Len(str) - 1) .Offset(, 1) = k End With str = "" k = 0 Next j ws2.Columns("A:E").AutoFit End Sub 何度も失礼しました。m(__)m
お礼
お礼が遅れて申し訳有りません。 ありがとうございました。
- jcctaira
- ベストアンサー率58% (119/204)
gx9wxさん こんにちは。 > 同じ値のF列内にカンマでつないで転記したいです。 F列内ではなくD列としました。 以下のマクロで可能かと思います。 ※シート2のタイトルは設定していません。また3行目から転記しています。 Sub 集計() Dim Dict As Object Dim Key As Variant Dim 分割 As Variant Dim 個数 As Variant Dim r As Long Sheets("Sheet1").Select Set Dict = CreateObject("Scripting.Dictionary") With Dict For r = 3 To Cells(Rows.Count, "D").End(xlUp).Row Key = Cells(r, "D") If .Exists(Key) = True Then .Item(Key) = .Item(Key) & "," & Cells(r, "C") Else .Add Key, Cells(r, "E") & "::" & Cells(r, "F") & "::" & Cells(r, "C") End If Next r r = 3 Sheets("Sheet2").Select For Each Key In .keys 分割 = Split(.Item(Key), "::") 個数 = Split(分割(2), ",") Cells(r, "A") = Key Cells(r, "B") = 分割(0) Cells(r, "C") = 分割(1) Cells(r, "D") = 分割(2) Cells(r, "E") = UBound(個数) + 1 r = r + 1 Next End With Cells.EntireColumn.AutoFit Set Dict = Nothing End Sub
お礼
お礼が遅れて申し訳有りません。 ありがとうございました。
補足
ありがとうございます。 一応自力で作成した物です。 Sheet1のD列に途中空白があるのが わかり苦戦しています。 Sub 転記2() '2011年9月9日 Dim 処理行 Dim 転記先行 Dim 最終行 Dim 比較値 Dim 元番号 Dim 追加番号 Dim 回数 Dim 員数 Sheets("Sheet1").Select 最終行 = Cells(Rows.Count, 1).End(xlUp).Row 転記先行 = 3 回数 = 1 For 処理行 = 3 To 最終行 比較行 = 処理行 - 1 比較値 = Cells(比較行, 4).Value If Cells(処理行, 4).Value <> 比較値 Then Sheets("Sheet2").Cells(転記先行, 1) = Sheets("Sheet1").Cells(処理行, 4) Sheets("Sheet2").Cells(転記先行, 2) = Sheets("Sheet1").Cells(処理行, 5) Sheets("Sheet2").Cells(転記先行, 3) = Sheets("Sheet1").Cells(処理行, 6) Sheets("Sheet2").Cells(転記先行, 4) = Sheets("Sheet1").Cells(処理行, 3) Sheets("Sheet2").Cells(転記先行, 5) = 1 転記先行 = 転記先行 + 1 回数 = 1 Else 回数 = 回数 + 1 転記先行 = 転記先行 - 1 元番号 = Cells(処理行, 3) 追加番号 = Sheets("Sheet2").Cells(転記先行, 4) 員数 = 追加番号 & "," & 元番号 Sheets("Sheet2").Cells(転記先行, 4).Value = 員数 Sheets("Sheet2").Cells(転記先行, 5) = 回数 転記先行 = 転記先行 + 1 End If 比較行 = 比較行 + 1 Next 処理行 End Sub
- tom04
- ベストアンサー率49% (2537/5117)
こんにちは! 色々考え方はあるかと思いますが・・・ 一例です。 (1)Sheet2の1行目にSheet1の項目名を表示 (2)Sheet2のA~C列にSheet1のE列データを重複なしに表示 (3)Sheet2・Sheet1の各データをそれぞれFor~NextでLoopし、文字列は「&」で連結・個数は「+」で一つずつプラス。 (4)Sheet2のD列に連結した文字列の一文字少ないものを表示。E列に個数をプラスしたものを表示 (5)文字列・個数のデータをクリアにして次の行へ! という考え方です。 Sub test() Dim i, j, k As Long Dim str As String Dim ws1, ws2 As Worksheet Set ws1 = Worksheets("sheet1") Set ws2 = Worksheets("sheet2") With ws2.Cells(1, 1) .Value = "品物" .Offset(, 1) = "生産国" .Offset(, 2) = "サイズ" .Offset(, 4) = "個数" 'Sheet1の項目名はこちらで勝手に入れています。 '尚、Sheet1のD列の項目名が不明ですので、Sheet2のD1セルは空白にしています。 End With For i = 3 To ws1.Cells(Rows.Count, 4).End(xlUp).Row If WorksheetFunction.CountIf(ws2.Columns(1), ws1.Cells(i, 5)) = 0 Then With ws2.Cells(Rows.Count, 1).End(xlUp).Offset(1) .Value = ws1.Cells(i, 5) .Offset(, 1) = ws1.Cells(i, 6) .Offset(, 2) = ws1.Cells(i, 7) End With End If Next i For j = 2 To ws2.Cells(Rows.Count, 1).End(xlUp).Row For i = 3 To ws1.Cells(Rows.Count, 4).End(xlUp).Row If ws1.Cells(i, 5) = ws2.Cells(j, 1) Then str = str & ws1.Cells(i, 4) & "," k = k + 1 End If Next i With ws2.Cells(j, 4) .Value = Left(str, Len(str) - 1) .Offset(, 1) = k End With str = "" k = 0 Next j ws2.Columns("A:E").AutoFit End Sub こんな感じではどうでしょうか?m(_ _)m
お礼
お礼が送れて申し訳有りません。 自己解決しました。 ありがとうございました。
補足
ありがとうございます。 一応自力で作成した物です。 Sheet1のD列に途中空白があるのが わかり苦戦しています。 Sub 転記2() '2011年9月9日 Dim 処理行 Dim 転記先行 Dim 最終行 Dim 比較値 Dim 元番号 Dim 追加番号 Dim 回数 Dim 員数 Sheets("Sheet1").Select 最終行 = Cells(Rows.Count, 1).End(xlUp).Row 転記先行 = 3 回数 = 1 For 処理行 = 3 To 最終行 比較行 = 処理行 - 1 比較値 = Cells(比較行, 4).Value If Cells(処理行, 4).Value <> 比較値 Then Sheets("Sheet2").Cells(転記先行, 1) = Sheets("Sheet1").Cells(処理行, 4) Sheets("Sheet2").Cells(転記先行, 2) = Sheets("Sheet1").Cells(処理行, 5) Sheets("Sheet2").Cells(転記先行, 3) = Sheets("Sheet1").Cells(処理行, 6) Sheets("Sheet2").Cells(転記先行, 4) = Sheets("Sheet1").Cells(処理行, 3) Sheets("Sheet2").Cells(転記先行, 5) = 1 転記先行 = 転記先行 + 1 回数 = 1 Else 回数 = 回数 + 1 転記先行 = 転記先行 - 1 元番号 = Cells(処理行, 3) 追加番号 = Sheets("Sheet2").Cells(転記先行, 4) 員数 = 追加番号 & "," & 元番号 Sheets("Sheet2").Cells(転記先行, 4).Value = 員数 Sheets("Sheet2").Cells(転記先行, 5) = 回数 転記先行 = 転記先行 + 1 End If 比較行 = 比較行 + 1 Next 処理行 End Sub
- KURUMITO
- ベストアンサー率42% (1835/4283)
マクロでなくても関数のみでも解決できますがマクロでなくてはいけないのでしょうか? みかんでも国内、国外、Sサイズ、Lサイズなどいろいろあると思うのですが、ミカンの行は1行でということなのでしょうか?
お礼
申し訳ありません。 マクロを起動をすると、15種類くらいの処理を してここにたどり着きます。 最後にこの処理を行い自動保存して終了です。 この処理もマクロで行いたいと思っています。 説明不足ですいません。 D列の値が同じ場合はE,F列も同じ値でG列のみ相違となります。 D列がみかんならE列は必ず国内、F列はSサイズです。 (実際にはもっと長い文字列なのですが例なので上記のように書きました。) よろしくお願いします。
補足
ありがとうございます。 一応自力で作成した物です。 Sheet1のD列に途中空白があるのが わかり苦戦しています。 Sub 転記2() '2011年9月9日 Dim 処理行 Dim 転記先行 Dim 最終行 Dim 比較値 Dim 元番号 Dim 追加番号 Dim 回数 Dim 員数 Sheets("Sheet1").Select 最終行 = Cells(Rows.Count, 1).End(xlUp).Row 転記先行 = 3 回数 = 1 For 処理行 = 3 To 最終行 比較行 = 処理行 - 1 比較値 = Cells(比較行, 4).Value If Cells(処理行, 4).Value <> 比較値 Then Sheets("Sheet2").Cells(転記先行, 1) = Sheets("Sheet1").Cells(処理行, 4) Sheets("Sheet2").Cells(転記先行, 2) = Sheets("Sheet1").Cells(処理行, 5) Sheets("Sheet2").Cells(転記先行, 3) = Sheets("Sheet1").Cells(処理行, 6) Sheets("Sheet2").Cells(転記先行, 4) = Sheets("Sheet1").Cells(処理行, 3) Sheets("Sheet2").Cells(転記先行, 5) = 1 転記先行 = 転記先行 + 1 回数 = 1 Else 回数 = 回数 + 1 転記先行 = 転記先行 - 1 元番号 = Cells(処理行, 3) 追加番号 = Sheets("Sheet2").Cells(転記先行, 4) 員数 = 追加番号 & "," & 元番号 Sheets("Sheet2").Cells(転記先行, 4).Value = 員数 Sheets("Sheet2").Cells(転記先行, 5) = 回数 転記先行 = 転記先行 + 1 End If 比較行 = 比較行 + 1 Next 処理行 End Sub
お礼
いろいろすいません。 質問した内容とデータがかなり異なる為、 空白には設定した文字を転記して その文字を使って除外したり、 そのA列の値をそのまま転記するなど またループを回避するなどして 解決しました。 ありがとうございました。