Excel VBA質問箱 IV

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

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


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

【71620】別ファイルを指定 G一朗 12/3/23(金) 13:23 質問[未読]
【71621】Re:別ファイルを指定 UO3 12/3/23(金) 13:49 発言[未読]
【71624】Re:別ファイルを指定 Abebobo 12/3/23(金) 14:15 発言[未読]
【71635】Re:別ファイルを指定 G一朗 12/3/23(金) 15:51 発言[未読]
【71636】Re:別ファイルを指定 UO3 12/3/23(金) 16:09 発言[未読]
【71625】Re:別ファイルを指定 UO3 12/3/23(金) 14:32 回答[未読]
【71627】Re:別ファイルを指定 UO3 12/3/23(金) 14:47 回答[未読]
【71637】Re:別ファイルを指定 G一朗 12/3/23(金) 16:09 発言[未読]

【71620】別ファイルを指定
質問  G一朗  - 12/3/23(金) 13:23 -

引用なし
パスワード
   Book1のSheet1で、
Book2のデータをBook3にコピーしたいときの記述について教えてください。

Book1のSheet1はこのようになっていて、パス・ファイル名とシート名、セルを
それぞれ入力できるようになっています。

 A      B   C D      E   F
1 C:\book2.XLS Sheet3 A1 C:\book3.XLS Sheet2 F1
2 C:\book2.XLS Sheet3 A2 C:\book3.XLS Sheet2 F2

この処理を記述するときに、

i = 1
Workbooks.Open Filename:=(Sheets("Sheet3").Range("M" & i))
Sheets(Sheets("Sheet3").Range("C" & i)).Range(Sheets("Sheet3").Range("D" & i)).Select
Selection.Copy
Workbooks.Open Filename:=(Sheets("Sheet3").Range("N" & i))
Sheets(Sheets("Sheet3").Range("K" & i)).Range(Sheets("Sheet3").Range("L" & i)).Select
Application.CutCopyMode = False
i = i + 1

と、書くとBook2を開いたあとは、Book1を指定し直せていないので、
当然ですが、Book2のシート名を取得できなくなります。
うまくBook1,2,3を指定し分ける方法がありましたら、
是非ご教授お願いします。

【71621】Re:別ファイルを指定
発言  UO3  - 12/3/23(金) 13:49 -

引用なし
パスワード
   ▼G一朗 さん:

こんにちは
アップされた方法以外のコードもありますが、その前に。

>Workbooks.Open Filename:=(Sheets("Sheet3").Range("M" & i))

("Sheet1") じゃないのですか?
また、Range("M" & i)) M列って何でしょうか?
それと、Book1 は、このマクロが書かれたブックですか?

次に、転記元ブックはBook2、転記先ブックはBook3 と決まっていないのですか?
それとも、各行ごとに、転記元ブックと転記先ブックがかわる可能性があるのですか?
もし決まっているとしたら、たとえば100行あったとして、Book2を100回、Book3も100回開くことになります。
随分、無駄なことだと思われませんか?

【71624】Re:別ファイルを指定
発言  Abebobo  - 12/3/23(金) 14:15 -

引用なし
パスワード
   そういう意味だったのですね。

サンプルを書いた後で投稿をちゅうちょしていました。

Sub Test()

Dim My_Book  As Workbook
Dim My_Sheet3 As Worksheet
Dim BooK_A  As Workbook

Set My_Book = ThisWorkbook 'マクロが書いてあるブック
Set My_Sheet3 = My_Book.Sheets("Sheet3")
Set BooK_A = Workbooks.Open(Filename:="C:\book2.XLS")

MsgBox My_Book.Name & Chr(10) & BooK_A.Name

Set My_Book = Nothing
Set My_Sheet3 = Nothing
Set BooK_A = Nothing
End Sub

こんな感じで、それぞれを変数に記憶させておくことをお勧めします。

【71625】Re:別ファイルを指定
回答  UO3  - 12/3/23(金) 14:32 -

引用なし
パスワード
   ▼G一朗 さん:

質問の回答をもらっていない段階ですが、コード案を3つ。

Sample1 は、アップされた方式、1行ごとにファイルを開いて転記するタイプ。
ただし、この場合、2行目が、また同じファイルかもしれません。
そうすると、同じブックを二度開こうとしてエラーになります。
ですので、毎回開いて、保存して閉じるということをしなければいけません。

Sample2 は 転記元ブックと転記先ブックが、それぞれ1つというタイプ。
最初の行でのみ、転記元ブックと転記先ブックを開きます。

さらに、Sample3は、Sample2の別案。開くファイルは転記先ブックのみです。

Sub Sample1()
  Dim c As Range
  Dim d As Variant
  
  Application.ScreenUpdating = False
  
  With ThisWorkbook.Sheets("Sheet1")
    For Each c In .Range("A1", .Range("A" & .Rows.Count).End(xlUp))
      Workbooks.Open c.Value
      d = ActiveWorkbook.Sheets(c.Offset(, 1).Value).Range(c.Offset(, 2).Value).Value
      ActiveWorkbook.Close False
      Workbooks.Open c.Offset(, 3).Value
      ActiveWorkbook.Sheets(c.Offset(, 4).Value).Range(c.Offset(, 5).Value).Value = d
      ActiveWorkbook.Close True
    Next
  End With
  
  Application.ScreenUpdating = True
  MsgBox "処理が終了しました"
 
  
End Sub

Sub Sample2()
  Dim c As Range
  Dim d As Variant
  Dim done As Boolean
  Dim wb2 As Workbook, wb3 As Workbook
  
  Application.ScreenUpdating = False
  
  With ThisWorkbook.Sheets("Sheet1")
    For Each c In .Range("A1", .Range("A" & .Rows.Count).End(xlUp))
      If Not done Then
        Set wb2 = Workbooks.Open(c.Value)
        Set wb3 = Workbooks.Open(c.Offset(, 3).Value)
        done = True
      End If
      
      wb3.Sheets(c.Offset(, 4).Value).Range(c.Offset(, 5).Value).Value = _
          wb2.Sheets(c.Offset(, 1).Value).Range(c.Offset(, 2).Value).Value
          
    Next
  End With
  
  wb2.Close False
  wb3.Close True
  
  Set wb2 = Nothing
  Set wb3 = Nothing
  
  Application.ScreenUpdating = True
  MsgBox "処理が終了しました"
  
End Sub

Sub Sample3()
  Dim c As Range
  Dim d As Variant
  Dim done As Boolean
  Dim wb3 As Workbook
  Dim myPath As String
  Dim fName As String
  Dim w As Variant
  
  Application.ScreenUpdating = False
  
  With ThisWorkbook.Sheets("Sheet1")
    For Each c In .Range("A1", .Range("A" & .Rows.Count).End(xlUp))
      If Not done Then
        Set wb3 = Workbooks.Open(c.Offset(, 3).Value)
        w = Split(c.Value, "\")
        fName = w(UBound(w))
        myPath = Left(c.Value, Len(c.Value) - Len(fName))
        done = True
      End If
      With wb3.Sheets(c.Offset(, 4).Value).Range(c.Offset(, 5).Value)
        .Formula = "='" & myPath & "[" & fName & "]" & c.Offset(, 1).Value & "'!" & c.Offset(, 2).Value
        .Value = .Value
      End With
      
    Next
  End With
  
  wb3.Close True
  
  Set wb3 = Nothing
  
  Application.ScreenUpdating = True
  MsgBox "処理が終了しました"
  
End Sub

【71627】Re:別ファイルを指定
回答  UO3  - 12/3/23(金) 14:47 -

引用なし
パスワード
   ▼G一朗 さん:

もう1つ。 転記先ブックが複数ありうる場合のコード案です。
処理の最初に転記先ブック名で並び替えをします。
Sample3と同じく、転記先ブックのみを開きます。

Sub Sample4()
  Dim c As Range
  Dim d As Variant
  Dim done As Boolean
  Dim wb3 As Workbook
  Dim myPath As String
  Dim fName As String
  Dim w As Variant
  
  Application.ScreenUpdating = False
  
  With ThisWorkbook.Sheets("Sheet1")
    .Cells.Sort key1:=Columns("D"), order1:=xlAscending, header:=xlYes
    For Each c In .Range("A1", .Range("A" & .Rows.Count).End(xlUp))
      If Not done Then
        Set wb3 = Workbooks.Open(c.Offset(, 3).Value)
        done = True
      End If
      
      w = Split(c.Value, "\")
      fName = w(UBound(w))
      myPath = Left(c.Value, Len(c.Value) - Len(fName))
        
      With wb3.Sheets(c.Offset(, 4).Value).Range(c.Offset(, 5).Value)
        .Formula = "='" & myPath & "[" & fName & "]" & c.Offset(, 1).Value & "'!" & c.Offset(, 2).Value
        .Value = .Value
      End With
      
      If c.Offset(, 3).Value <> c.Offset(1, 3).Value Then wb3.Close True
      
    Next
  End With
  
  Set wb3 = Nothing
  
  Application.ScreenUpdating = True
  MsgBox "処理が終了しました"
  
End Sub

【71635】Re:別ファイルを指定
発言  G一朗  - 12/3/23(金) 15:51 -

引用なし
パスワード
   ▼UO3 さん:
>アップされた方法以外のコードもありますが、その前に。

失礼しました。実際のシートは他にも記載があるため
例では簡略化したのに、コードがそのままでした・・・。
下のようになります。

i = 1
Workbooks.Open Filename:=(Sheets("Sheet1").Range("A" & i))
Sheets(Sheets("Sheet1").Range("B" & i)).Range(Sheets("Sheet1").Range("C" & i)).Select
Selection.Copy
Workbooks.Open Filename:=(Sheets("Sheet1").Range("D" & i))
Sheets(Sheets("Sheet1").Range("E" & i)).Range(Sheets("Sheet1").Range("F" & i)).Select
Application.CutCopyMode = False
i = i + 1

>それと、Book1 は、このマクロが書かれたブックですか?

マクロはBook1に記載しています。
Book2とか3にはマクロの記述はありません。

>次に、転記元ブックはBook2、転記先ブックはBook3 と決まっていないのですか?
>それとも、各行ごとに、転記元ブックと転記先ブックがかわる可能性があるのですか?
転記先が複数になることはあまりないので、転記先はファイル参照はスキップしようと考えていますが、
転記元は複数ファイルあるのでこういう形で考えています。

>もし決まっているとしたら、たとえば100行あったとして、Book2を100回、Book3も100回開くことになります。
>随分、無駄なことだと思われませんか?
さすがに、1ファイルから100セル転記するのに、
100回ファイルを開くなんてことは、随分無駄なことだと私だって思いますから、
こんなマクロを組もうと思わないですし、こんな質問はしてないですね。

【71636】Re:別ファイルを指定
発言  UO3  - 12/3/23(金) 16:09 -

引用なし
パスワード
   ▼G一朗 さん:

さすがに、1ファイルから100セル転記するのに、
>100回ファイルを開くなんてことは、随分無駄なことだと私だって思いますから、
>こんなマクロを組もうと思わないですし、こんな質問はしてないですね。

そうでしょうね。

アップされたコードが

>i = 1
>略
>i = i + 1

になっていましたから、これは、この外側にループがあるんだろうなと。
そうすると、次の実行で(既に申し上げたとおり)同じファイルを開く可能性があり
エラーになる。だから「毎回閉じざるを得ないですね」ということなんですよ。

いずれにしても、いくつかコード案をアップしています。
おそらく Sample4 が今回の要件にマッチしているんだろうと思います。

お試しください。

【71637】Re:別ファイルを指定
発言  G一朗  - 12/3/23(金) 16:09 -

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

ありがとうございます。
提示頂いたコードでやってみます。

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