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

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

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

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

Q&A

2回答

3084閲覧

複数ブック、複数シートからの値コピー

m73

総合スコア6

VBA

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

0グッド

0クリップ

投稿2018/05/11 07:16

編集2018/05/11 07:50

前提・実現したいこと

[実現したいこと]
VBAにて集計表を作成しております。
勉強をし始め、数日です。
複数ブックの複数シートから値のみコピーしたいと思っています。

[前提]
・集計元は1つのフォルダにまとまっている
・集計元は複数のブックにわかれている
またBookの名前もまちまちである。
Book1.xlsx、ABC.xlsx、111.xlsx・・・
・集計元の1つのブックには複数のシートが含まれている
シートの枚数、名前はブックによってまちまち
・各シートはブックが分かれていても全て共通のフォーマット

①集計元のブック(元データが記載されている)の各シートのA2のセルをコピー → 集計先のB列に貼り付け
②集計元のブック(元データが記載されている)のD2のセルをコピー → 集計先のC列に貼り付け
③集計元のブック、シート名をA列にはりつけ

ということをおこないたいです。
やりたいことと乖離してしまっているためご教示を頂きたいです。

発生している問題・エラーメッセージ

まず前提の①が行えるか試した所、以下を実行すると
1つ目のブックの各シートをコピーしましたが
2つ目のブックを開いたあと、1つ目の下データのブックの値に上書きされてしまいました。

また②の、集計元のブック(元データが記載されている)のD2のセルをコピー → 集計先のB列に貼り付けに関しても変数が複数になると理解がおいついておりません。

言い訳にするつもりではないのですが、
勉強が浅いため、作成したコードもお見苦しい点ばかりかと思います。
何卒お力お借りしたく思います。

該当のソースコード

VBA

1 2Sub TEST() 3Dim myPath As String 4Dim myFile As String 5Dim i As Long 6 7myPath = ThisWorkbook.Path 8myFile = Dir(myPath & "\" & "*.xlsx") 9 10Do Until myFile = "" 11 12Workbooks.Open myPath & "\" & myFile 13Sheets("Sheet1").Select 14For i = 1 To Worksheets.Count 15 16Worksheets(i).Range("A2").Copy 17 18ThisWorkbook.Worksheets("Sheet1").Cells(i, 1).PasteSpecial _ 19xlPasteValuesAndNumberFormats 20 21Next i 22 23myFile = Dir() 24 25Loop 26End Sub

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

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

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

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

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

coco_bauer

2018/05/11 07:24

複数のシートを持つ複数のブックから、A2セルとD2セルの内容を収集するだけで良いのですか? 情報源となったブックの名前とワークシートの名前ぐらいは残さないと、後で困るのではないかと危惧します。
m73

2018/05/11 07:29

>coco_bauer様  仰られるとおりです、ご指摘切に感謝いたします。質問を一部編集させて頂きます。
m.ts10806

2018/05/11 07:41

プログラムコード(およびエラーメッセージ)は```で囲ってください。(わからなければ質問編集画面でコード部分を選択し<code>ボタンを押してください)正しく反映されているかどうかは質問編集画面のプレビューを見ながら編集していってください。
m73

2018/05/11 07:49

>mts10806様 失礼いたしました。ご指摘感謝いたします。早々に修正いたします。
guest

回答2

0

まずは、確認。
集計元と集計先のブックは同じフォルダーにあるのですか。
(コードを見る限りは同じフォルダーですね。)
また、このマクロは集計先のファイルにあるのですね。

上記があっているとして、

DoループでDir関数を使ってファイル名を順次取得する部分と、Forループで各シートを順次取得して処理していく部分はいいですが、Forのループ変数(i)を行インデックスしているのが間違いですね。
別ブックへ移行するときに、1 に戻ってしまいますので、同じところを上書きすることになります。

入力行用の変数を別に用意して、カウントアップするようにする必用があります。

現状のコードをなるべく活かして、上記の点と、A列にブック名!シート名の入力も追加したコード例をとりあえず提示します。

VBA

1Sub 取り込みテスト() 2 Dim myPath As String 3 Dim myFile As String 4 Dim MyBook As Workbook 5 Dim CurRow As Long '入力する行インデックス 6 Dim i As Long 7 8 myPath = ThisWorkbook.Path 9 myFile = Dir(myPath & "\" & "*.xlsx") 10 CurRow = 1 11 Do Until myFile = "" 12 Workbooks.Open myPath & "\" & myFile 13' Sheets("Sheet1").Select ←不必要だし、「Sheet1」という名前のシートがなければエラーになる 14 For i = 1 To Worksheets.Count 15 Worksheets(i).Range("A2").Copy 16 ThisWorkbook.Worksheets("Sheet1").Cells(CurRow, 2).PasteSpecial _ 17 xlPasteValuesAndNumberFormats 18 Worksheets(i).Range("D2").Copy 19 ThisWorkbook.Worksheets("Sheet1").Cells(CurRow, 3).PasteSpecial _ 20 xlPasteValuesAndNumberFormats 21 ThisWorkbook.Worksheets("Sheet1").Cells(CurRow, 1).Value = myFile & "!" & Worksheets(i).Name 22 CurRow = CurRow + 1 '入力行をカウントアップ 23 Next i 24 25 myFile = Dir() 26 Loop 27 28End Sub

これで希望の動作にはなると思います。
ただ、アクティブブック、シートが移動するのでチラツキますし、
クリップボード経由なので処理も重いです。
また、ブックが開きっぱなしなのも気になりますね。

この辺りは完全の余地が大です。
ヒントを出しておきますと、
Application.ScreenUpdating を使って画面更新を抑止するとチラツキを抑制できます。
Copy PasteSpecial を使わなくても、代入という処理で値を入力できます。

追記

タッチの差で、imihitoさんに先を越されました。しかも、より完成度の高いコードです。
まずは、私のコードは、元のコードとほぼと同じなので意味はすぐ理解できると思います。
それを理解した上で、imihitoさんのコードを、私との違いを意識しながら、読むと理解が捗ると思います。

上記のコードの改良版

Sub 取り込みテスト() Dim myPath As String Dim myFile As String Dim FromBook As Workbook '集計元ブック Dim ToSheet As Worksheet '集計先シート Dim CurRow As Long '入力する行インデックス Dim i As Long Set ToSheet = ThisWorkbook.Worksheets("Sheet1") ' myPath = ThisWorkbook.Path & "\" myFile = Dir(myPath & "*.xlsx") Application.ScreenUpdating = False '画面更新の抑制 CurRow = 1 Do Until myFile = "" Set FromBook = Workbooks.Open(myPath & "\" & myFile) '開いたブックを変数にセット For i = 1 To FromBook.Worksheets.Count With FromBook.Worksheets(i) ToSheet.Cells(CurRow, 1).Value = myFile & "!" & .Name ToSheet.Cells(CurRow, 2).Value = .Range("A2").Value ToSheet.Cells(CurRow, 3).Value = .Range("D2").Value End With CurRow = CurRow + 1 '次の行に移動 Next i FromBook.Close '集計元ブックを閉じる myFile = Dir() Loop Application.ScreenUpdating = True MsgBox "取り込み完了しました。" End Sub

投稿2018/05/11 14:02

編集2018/05/11 14:45
hatena19

総合スコア33694

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

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

0

変数が複数になると理解がおいついておりません。

変数は使いたい値に対するメモのようなものです。
メモの名前が適当だと何を表しているのかわかりにくいため、自分がわかりやすい名前を付けてあげると上手くようになると思います。

VBAのデバッグ時に便利な機能

ローカルウィンドウ

ローカル変数(プロシージャの中で作った変数)の中身を簡単に確認できるウィンドウです。
ステップ実行や、ブレークポイントと組み合わせると、今どんな状態なのか、を簡単に確認できます。

イミディエイトウィンドウ

ローカルウィンドウで変数の中はある程度は見えますが、一部確認できないものもあります。
そのような場合は、イミディエイトウィンドウを使用すると、その場で簡単なコードを実行して結果を確認できます。

vba

1'イミディエイトウィンドウ内:値の確認 2?Range("A1").Value '~Valueまで入力してEnter→A1セルの値が表示される

vba

1'イミディエイトウィンドウ内:何か実行 2Range("A1").Select '~Selectまで入力してEnter→A1セルが選択される

①集計元のブック(元データが記載されている)の各シートのA2のセルをコピー → 集計先のB列に貼り付け

の部分だけサンプルを作ってみました。

若干変数過多の気はありますが参考になれば。

vba

1Sub TEST2() 2 3 'コピー先のシート 4 Dim copyToSheet As Worksheet 5 Set copyToSheet = ThisWorkbook.Worksheets("Sheet1") 6 7 '集計元A2セルのコピー先(開始位置) 8 '適当な名前なので、値の意味を踏まえた名前にした方が良い 9 Dim A2CopyToCell As Range 10 Set A2CopyToCell = copyToSheet.Range("B1") 11 12 'xlsxファイルを検索するフォルダ(末尾\付き) 13 'ThisWorkbook.Path & "\" はなんども出てくるので先にまとめてしまう 14 Dim searchFolderPath As String 15 searchFolderPath = ThisWorkbook.Path & "\" 16 17 '見つかったxlsxファイルの名前 18 Dim findXlsxName As String 19 findXlsxName = Dir(searchFolderPath & "*.xlsx") 20 21 Do Until findXlsxName = "" 22 23 'コピー元のブックを開く 24 Dim copyFromBook As Workbook 25 Set copyFromBook = Workbooks.Open(searchFolderPath & findXlsxName) 26 27 'For Each は「何かの集まり全て」(今回は`copyFromBook`のワークシート全て)に対して処理をする 28 Dim ws As Worksheet 29 For Each ws In copyFromBook.Worksheets 30 '`ws`には 元のコードでの`Worksheets(i)`に相当するものが自動で入ります 31 32 '①集計元のブック(元データが記載されている)の各シートのA2のセルをコピー → 集計先のB列に貼り付け 33 Dim A2CopyFromCell As Range 34 Set A2CopyFromCell = ws.Range("A2") 35 36 'コピー先のセルの値にコピー元のセルの値を入れる 37 A2CopyToCell.Value = A2CopyFromCell.Value 38 39 40 '次のコピー先のセルは、今のコピー先のセルから1行0列動いたセル(→1つ下のセル) 41 Set A2CopyToCell = A2CopyToCell.Offset(1, 0) 42 43 '②集計元のブック(元データが記載されている)のD2のセルをコピー → 集計先のC列に貼り付け 44 'TODO 45 46 '③集計元のブック、シート名をA列にはりつけ 47 'TODO 48 '集計元のブックの名前→copyFromBook.Name 49 'シート名→ws.Name 50 51 52 Next ws 53 54 findXlsxName = Dir() 55 56 Loop 57 58End Sub

投稿2018/05/11 14:01

imihito

総合スコア2166

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問