Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


542 / 13645 ツリー ←次へ | 前へ→

【79775】VBA初心者です。ブック間の列コピーを繰り返す方法について atori 18/4/10(火) 15:08 質問[未読]
【79777】Re:VBA初心者です。ブック間の列コピーを繰... マナ 18/4/10(火) 22:53 発言[未読]
【79778】Re:VBA初心者です。ブック間の列コピーを繰... atori 18/4/11(水) 14:10 回答[未読]
【79781】Re:VBA初心者です。ブック間の列コピーを繰... マナ 18/4/11(水) 22:11 発言[未読]
【79783】Re:VBA初心者です。ブック間の列コピーを繰... atori 18/4/12(木) 10:09 回答[未読]
【79786】Re:VBA初心者です。ブック間の列コピーを繰... マナ 18/4/12(木) 20:10 発言[未読]
【79787】Re:VBA初心者です。ブック間の列コピーを繰... atori 18/4/13(金) 11:04 発言[未読]
【79795】Re:VBA初心者です。ブック間の列コピーを繰... マナ 18/4/14(土) 10:33 発言[未読]
【79796】Re:VBA初心者です。ブック間の列コピーを繰... マナ 18/4/14(土) 13:00 発言[未読]
【79799】Re:VBA初心者です。ブック間の列コピーを繰... atori 18/4/16(月) 11:41 発言[未読]
【79801】Re:VBA初心者です。ブック間の列コピーを繰... マナ 18/4/16(月) 20:04 発言[未読]
【79803】Re:VBA初心者です。ブック間の列コピーを繰... atori 18/4/17(火) 10:43 お礼[未読]
【79808】Re:VBA初心者です。ブック間の列コピーを繰... マナ 18/4/17(火) 19:00 発言[未読]
【79817】Re:VBA初心者です。ブック間の列コピーを繰... atori 18/4/18(水) 16:11 お礼[未読]

【79775】VBA初心者です。ブック間の列コピーを繰...
質問  atori  - 18/4/10(火) 15:08 -

引用なし
パスワード
   VBAを用いてブック間での列のコピーを繰り返しで行おうと思っているのですが、繰り返しのステートメントと別ブックからのコピーを繰り返すステートメントを複合させようとしたものの方法がわかりませんでした。

【コピー先】
固定ブック
【コピー元】
同フォルダ内で1.xlsx,2.xlsx,3.xlsx,4.xlsx,....と続く整数のブック

【行いたいこと】
・コピー元ブックのB列(固定)を、コピー先ブックのA列にペースト
・次の番号のコピー元ブックのB列を、コピー先ブックのB列にペースト
・次の番号のコピー元ブックのB列を、コピー先ブックのC列にペースト

・ 以下繰り返し


この場合、どのようなマクロを用いればいいのでしょうか。
ご助力よろしくおねがいします。m(_ _)m

【79777】Re:VBA初心者です。ブック間の列コピーを...
発言  マナ  - 18/4/10(火) 22:53 -

引用なし
パスワード
   ▼atori さん:

まずは、繰り返し構文を使わないで、
1.xlsx,2.xlsx,3.xlsx,4.xlsxの4つについて
コピーするマクロを考えてみてください。

【79778】Re:VBA初心者です。ブック間の列コピーを...
回答  atori  - 18/4/11(水) 14:10 -

引用なし
パスワード
   ▼マナ さん:

ご返信ありがとうございます!
ファイルパスは仮のものですが、1.xlsx ~ 4.xlsxで考えた分では以下のようになりました。

Sub exam1()

  Dim wb As Workbook
  Dim ws As Worksheet
  Dim wsx As Worksheet
  
  Set wb = Application.Workbooks.Open("C:\Users\user\Desktop\Sample\1.xlsx")
  Set ws = wb.Worksheets("Sheet1")
  Set wsx = ThisWorkbook.Worksheets("Sheet1")

  ws.Range("B:B").Copy
  wsx.Range("B:B").PasteSpecial Paste:=xlValues

  wb.Save
  wb.Close
  Set wb = Application.Workbooks.Open("C:\Users\user\Desktop\Sample\2.xlsx")

  ws.Range("B:B").Copy
  wsx.Range("C:C").PasteSpecial Paste:=xlValues

  wb.Save
  wb.Close
  Set wb = Application.Workbooks.Open("C:\Users\user\Desktop\Sample\3.xlsx")

  ws.Range("B:B").Copy
  wsx.Range("D:D").PasteSpecial Paste:=xlValues

  wb.Save
  wb.Close
  Set wb = Application.Workbooks.Open("C:\Users\user\Desktop\Sample\4.xlsx")

  ws.Range("B:B").Copy
  wsx.Range("E:E").PasteSpecial Paste:=xlValues

  wb.Save
  wb.Close

End Sub

いかがでしょうか…?

【79781】Re:VBA初心者です。ブック間の列コピーを...
発言  マナ  - 18/4/11(水) 22:11 -

引用なし
パスワード
   ▼atori さん:
 
>  Set wb = Application.Workbooks.Open("C:\Users\user\Desktop\Sample\1.xlsx")

1)Application.は省略できます。というか普通は省略します。
他のapplication例えばWordのマクロでExcelを開くとかだと必須ですが
ほとんどの場合、不要です。

>  Set ws = wb.Worksheets("Sheet1")
>  Set wsx = ThisWorkbook.Worksheets("Sheet1")
>
>  ws.Range("B:B").Copy
>  wsx.Range("B:B").PasteSpecial Paste:=xlValues
>
>  wb.Save
>  wb.Close

2)保存する必要がありますか?
保存しないで閉じるだけでよいのではありませんか。

>  Set wb = Application.Workbooks.Open("C:\Users\user\Desktop\Sample\2.xlsx")
>
>  ws.Range("B:B").Copy

3)変数wsは、毎回SETしなおす必要があります。
このままだと、wsは、最初のブックのSheet1のままで、
すでにブックは閉じた後なので、エラーになると思います。


>  wsx.Range("C:C").PasteSpecial Paste:=xlValues

4)B列は、2列めなので、Columns(2)、
C列は、3列めなので、Columns(3)と記述できます。
繰り返し処理したいときには、このほうがよいです。
k回目の貼付け先は、Columns(k+1)と記述できるからです。


以上を踏まえて、修正していただけますか。

【79783】Re:VBA初心者です。ブック間の列コピーを...
回答  atori  - 18/4/12(木) 10:09 -

引用なし
パスワード
   ▼マナ さん:

親切なご指導、ありがとうございます…!
分かりやすくてとても助かります(゜-゜)

>1)Application.は省略できます。というか普通は省略します。
>他のapplication例えばWordのマクロでExcelを開くとかだと必須ですが
>ほとんどの場合、不要です。

省略できるのですね…。自分でも改めて調べてみたら、殆ど本来はApplication.が付いているものなんですね。

>2)保存する必要がありますか?
>保存しないで閉じるだけでよいのではありませんか。

確かに保存はしなくても大丈夫です…!

>3)変数wsは、毎回SETしなおす必要があります。
>このままだと、wsは、最初のブックのSheet1のままで、
>すでにブックは閉じた後なので、エラーになると思います。

変数の値の参照元が変わっても、自動で変更されるわけではないのですね!

>4)B列は、2列めなので、Columns(2)、
>C列は、3列めなので、Columns(3)と記述できます。
>繰り返し処理したいときには、このほうがよいです。
>k回目の貼付け先は、Columns(k+1)と記述できるからです。

おお、たしかに数字であれば+1が使えますね…

>以上を踏まえて、修正していただけますか。

Sub exam1()

  Dim wb As Workbook
  Dim ws As Worksheet
  Dim wsx As Worksheet
  
  Set wb = Workbooks.Open("C:\Users\user\Desktop\Sample\1.xlsx")
  Set ws = wb.Worksheets("Sheet1")
  Set wsx = ThisWorkbook.Worksheets("Sheet1")

  ws.Columns(2).Copy
  wsx.Columns(2).PasteSpecial Paste:=xlValues

  wb.Close
  Set wb = Workbooks.Open("C:\Users\user\Desktop\Sample\2.xlsx")
  Set ws = wb.Worksheets("Sheet1")

  ws.Columns(2).Copy
  wsx.Columns(3).PasteSpecial Paste:=xlValues

  wb.Close
  Set wb = Workbooks.Open("C:\Users\user\Desktop\Sample\3.xlsx")
  Set ws = wb.Worksheets("Sheet1")

  ws.Columns(2).Copy
  wsx.Columns(4).PasteSpecial Paste:=xlValues

  wb.Close
  Set wb = Workbooks.Open("C:\Users\user\Desktop\Sample\4.xlsx")
  Set ws = wb.Worksheets("Sheet1")

  ws.Columns(2).Copy
  wsx.Columns(5).PasteSpecial Paste:=xlValues

  wb.Close

End Sub

よろしくおねがいします!

【79786】Re:VBA初心者です。ブック間の列コピーを...
発言  マナ  - 18/4/12(木) 20:10 -

引用なし
パスワード
   ▼atori さん:

>wb.Close

wb.Close False

としたほうがよいです。
・保存しないことがわかりやすい
・保存するかそうかの確認メッセージが出ない
からです。

----

そうすると

Set wb = Workbooks.Open("C:\Users\user\Desktop\Sample\1.xlsx")
Set ws = wb.Worksheets("Sheet1")
ws.Columns(2).Copy
wsx.Columns(2).PasteSpecial Paste:=xlValues
wb.Close False

この5行が1つのブックについての処理になります。
よくみると、変数wsは1回しか使っていない。
ならば。変数は使わなくてもよいかもしれません。

Set wb = Workbooks.Open("C:\Users\user\Desktop\Sample\1.xlsx")
wb.Worksheets("Sheet1").Columns(2).Copy
wsx.Columns(2).PasteSpecial Paste:=xlValues
wb.Close False

こんな感じです。
これを4回繰り返せばよいことがわかりますよね。
繰り返しの中で、変化させる部分は2箇所

1.xlsx、wsx.Columns(2)

2.xlsx、wsx.Columns(3)

3.xlsx、wsx.Columns(4)

4.xlsx、wsx.Columns(5)

規則性はわかると思います。
これを

For k=1 to 4
 処理
Next

のように繰り返し構文で記述してみてください。
で、動作確認してみてください。
これをベースに完成形に近づけていくことになると思います。

【79787】Re:VBA初心者です。ブック間の列コピーを...
発言  atori  - 18/4/13(金) 11:04 -

引用なし
パスワード
   ▼マナ さん:
>▼atori さん:
>
>>wb.Close
>↓
>wb.Close False
>
>としたほうがよいです。
>・保存しないことがわかりやすい
>・保存するかそうかの確認メッセージが出ない
>からです。

確かにメッセージが出ないのは大きいですね…。
「クリップボードに大きな情報があります」のメッセージも出てしまうので、それに関するものも入れてみました。

本当に分かりやすいご説明ありがとうございます!
教えていただいた方法で作ってみたところ、以下のマクロで1~4.xlsxまでは動作しました…!

Sub Exam1()
'
' exam1 Macro
'
  Dim wb As Workbook
  Dim ws As Worksheet
  Dim wsx As Worksheet

  For k = 1 To 4

    Set wb = Workbooks.Open("C:\Users\user\Desktop\Exam\" & k & ".xlsx")
    Set wsx = ThisWorkbook.Worksheets("Sheet1")
    wb.Worksheets("Sheet1").Columns(2).Copy
    wsx.Columns(k + 1).PasteSpecial Paste:=xlValues
    wb.Application.CutCopyMode = False
    wb.Close False

  Next k

End Sub

CutCopyModeの前のApplicationや、後ろの=に関しては一回消してみたのですが、エラーメッセージが出てしまいました。

ここから、kをある程度大きな数字にしてエラーメッセージが出たら終了(つまりフォルダに存在するブックの数に達すれば終わり)という形でも良いのですが、自動的にフォルダ内のブック数を判別する方法もあるんですかね…?

【79795】Re:VBA初心者です。ブック間の列コピーを...
発言  マナ  - 18/4/14(土) 10:33 -

引用なし
パスワード
   ▼atori さん:


>「クリップボードに大きな情報があります」のメッセージも出てしまうので、それに関するものも入れてみました。
>
>    wb.Worksheets("Sheet1").Columns(2).Copy
>    wsx.Columns(k + 1).PasteSpecial Paste:=xlValues
>    wb.Application.CutCopyMode = False


その対応で、よいと思います。

貼付け先,Value = コピー元.Value
という構文を使っても、メッセージはでないかもしれません。
こんな感じです。

wsx.Columns(k + 1).Value = wb.Worksheets("Sheet1").Columns(2).Value

確認してみてください。
コピー範囲が大きいと、処理速度が落ちるかも知れませんが
コードが簡潔になるので、わたしはよく使います。

------

>自動的にフォルダ内のブック数を判別する方法もあるんですかね…?

Dir関数やFilesystemobjectを使えばよいと思いますが
余裕がれば検索してみるとよいです。
簡単にサンプルが見つかると思います。
フォルダ内のすべてのブックに同じ処理したいといったマクロでは
どちらかが、使われることが多いです。

ただ、わたしなら、結果が同じであれば、それでいいので
今回は、手抜きして

>ここから、kをある程度大きな数字にして

でよいかと考えます。
ただし、好みかもしれませんが、

>エラーメッセージが出たら終了

ではなく、その番号のブックが存在するかをDir関数で確認し
しなければ、Exit forでループを抜ける

といった感じにします。
そうすると、今のコードを、ほぼそのまま使えます。
Dir関数についてはネットで検索してみてください。

【79796】Re:VBA初心者です。ブック間の列コピーを...
発言  マナ  - 18/4/14(土) 13:00 -

引用なし
パスワード
   ▼atori さん:

>    Set wsx = ThisWorkbook.Worksheets("Sheet1")

これは、ループの外で、最初に1回実行でよいです。
わかりますよね。

【79799】Re:VBA初心者です。ブック間の列コピーを...
発言  atori  - 18/4/16(月) 11:41 -

引用なし
パスワード
   ▼マナ さん:
>
>wsx.Columns(k + 1).Value = wb.Worksheets("Sheet1").Columns(2).Value
>
>確認してみてください。
>コピー範囲が大きいと、処理速度が落ちるかも知れませんが
>コードが簡潔になるので、わたしはよく使います。

>>エラーメッセージが出たら終了
>
>ではなく、その番号のブックが存在するかをDir関数で確認し
>しなければ、Exit forでループを抜ける
>
>といった感じにします。
>そうすると、今のコードを、ほぼそのまま使えます。
>Dir関数についてはネットで検索してみてください。

>>    Set wsx = ThisWorkbook.Worksheets("Sheet1")
>
>これは、ループの外で、最初に1回実行でよいです。
>わかりますよね。

ありがとうございます!返信遅れて申し訳ありません。
コードが長くなると多分自分でもよくわからなくなって来てしまうので、コピー・ペーストは一行にまとめました!
Dir関数については調べたところ、If文と組み合わせるのがよいかと思ったので下記の通りに組んでみました。Elseをどういった形にするかで迷っていたのですが、消してみても問題なかったのでそのままにしてあります。
wsxはおっしゃる通りでした…!

Sub Exam1()
'
' exam1 Macro
'
  Dim wb As Workbook
  Dim ws As Worksheet
  Dim wsx As Worksheet
  Dim FileNumber As String

  Set wsx = ThisWorkbook.Worksheets("Sheet1")

  For k = 1 To 999

    Set wb = Workbooks.Open("C:\Users\user\Desktop\exam\" & k & ".xlsx")
    wsx.Columns(k + 1).Value = wb.Worksheets("Sheet1").Columns(2).Value
    wb.Close False

    FileNumber = Dir("C:\Users\user\Desktop\exam\" & k + 1 & ".xlsx")
    
  If FileNumber = "" Then
    Exit For
  End If

  Next k

End Sub

今回も4つ分のファイルで行ったのですが、エラーメッセージはありませんでした!

【79801】Re:VBA初心者です。ブック間の列コピーを...
発言  マナ  - 18/4/16(月) 20:04 -

引用なし
パスワード
   ▼atori さん:

1)ブックの存在確認の記述位置を変更しました。
2)保存先フォルダの記述方法を変更しました。
www.moug.net/tech/exvba/0060052.html


  Set wsx = ThisWorkbook.Worksheets("Sheet1")
  
  myPath = CreateObject("WScript.Shell").SpecialFolders("Desktop") & "\exam\"

  For k = 1 To 999
    myF = myPath & k & ".xlsx"
    If Dir(myF) = "" Then Exit For
    
    Set wb = Workbooks.Open(myF)
    wsx.Columns(k + 1).Value = wb.Worksheets("Sheet1").Columns(2).Value
    wb.Close False

  Next k

【79803】Re:VBA初心者です。ブック間の列コピーを...
お礼  atori  - 18/4/17(火) 10:43 -

引用なし
パスワード
   ▼マナ さん:

>1)ブックの存在確認の記述位置を変更しました。
>2)保存先フォルダの記述方法を変更しました。
>www.moug.net/tech/exvba/0060052.html

ありがとうございます!CreateObjectっていう手もあるんですね…

初めは至らぬところばかりでしたが、判りやすいご指導のおかげでマクロの作成だけではなくやっていることを理解するところまで行けました…!
最初に教えてくださったのがマナさんで良かったと思います、、、本当にありがとうございます(#^^#)

【79808】Re:VBA初心者です。ブック間の列コピーを...
発言  マナ  - 18/4/17(火) 19:00 -

引用なし
パスワード
   ▼atori さん:


>ここから、kをある程度大きな数字にして

わたしは、全く気にしないのですが
もし、気になるなら、

>For k = 1 To 999

でなく、Do〜Loopを使う方法もあります。
ちゃんと、ループを抜ける条件を設定しないと
無限ループになり、マクロが終わらなくなるので
わたしは、For〜Nextを多用しています。

Do
  k = k + 1
  myF = myPath & k & ".xlsx"
  If Dir(myF) = "" Then Exit Do
  
  省略

Loop

【79817】Re:VBA初心者です。ブック間の列コピーを...
お礼  atori  - 18/4/18(水) 16:11 -

引用なし
パスワード
   ▼マナ さん:

>>For k = 1 To 999
>
>でなく、Do〜Loopを使う方法もあります。

kがはっきりしない場合だと見た目(?)としてはこっちのほうが良さそうですね、、、
でも確かに汎用性で考えるとFor使っておいたほうが安心みたいなところもありますね。ありがとうございます!

542 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free