見出し画像

箸休め_9

VBAでFileを複製する

今回もご覧いただきありがとうございます。
前回の「VBAでファイル共有」の中で、同じBookを「共有するPCの台数分つくる。」と言いましたが、PCの台数が増えたり、イベントごとに参加者名簿が変わったりと、運用を繰り返す中で、対応が地味に面倒になります。
そこで、今回は複製を手処理に代わりExcelさんにお願いすることにします。

今回つくるBook「Copy.xlsm」

画面の例では、複製をつくる場所と、その数量を指定してVBAに依頼すると、その結果が得られる仕掛けをつくります。

「複製」指示画面

この例では、10行G列にFolder名、12行G列に複製の数量を入力するようにしています。
そして、10行G列が空白のときは、自身と同じFolderに、入力が有るときはその名前で新たなFolderをつくり、その中に12行G列の数量分を複製します。

それでは、Algorithmから考えてみましょう。
今回のメインはFolderをつくることとFile(Book)をコピーすることです。

まず、Folder作成は「MkDir」(Make Directory:Directory≒Folderをつくる)を使います。
構文は、MkDir DR & Cells(10, "G")ですが、予め
DR = ThisWorkbook.Path & "¥"として「自身が居る場所」としておくと、
Cells(10, "G")に入力された文字列名のFolderを、自身が居るFolder内につくるとなります。
最後の¥は、区切り文字として必要なので忘れないように注意しましょう。

それから、ファイルコピーはそのまま「FileCopy」を使います。
構文は、FileCopy DR & Bn, DT & Btで複製元のFile(在処とファイル名),複製先のFile(置き場とファイル名)を指定します。
DRは前述と同じく自身のPathで、DTは条件によって、新たなFolderをつくった場合は、そのFolderまでのPath。新たなFolderをつくらなかった場合は自身のPathとなります。
そして、このFileCopyを数量分繰り返します。

それでは、コーディングしながら詳細を説明します。
Procedure名を「複製」としてSub 複製()から始めます。
今回は、直下にOn Error GoTo Exを入れて、なにかしらのエラーがあったらラベルExに飛ぶようにしておきます。
ここから通常のLogicです。
DR = ThisWorkbook.Path & "¥"で自身の居場所を知るところからはじめます。
次にFn = 2を入れます。
これは、前述の説明では特に触れていませんでしたが、後述の繰り返しで必要な指標となるもので、初期値を2とします。
そして、10行G列のセルが空白でないときDRの中に指定のフォルダをつくりるために
If Cells(10, "G") <> "" Then
 MkDir DR & Cells(10, "G"): Fn = 1
End If
が入ります。
また、フォルダ作成時のFnは1としています。

ここから、Book複製です。
複写元のBook「受付_PC1.xlsm」をBnとすると
 Bn = "受付_PC1.xlsm"
複写先のフォルダ
DTとすると
 DT = DR & Cells(10, "G") & "¥"
となりますが、新たにフォルダをつくった場合はそのPath(DR & Cells(10, "G"))、つくらなかった場合は、Cells(10, "G")が空白のため結果的に自身のPath(DR)となります。
複製する数量を変数Cnに受け取り、念のためにCnが空白または、2より小さいときは”NG"とします。
Cn = Cells(12, "G")
If Cn = "" Or Cn < 2 Then Cn = "NG"

これを数量分繰り返すので、繰り返しの構文により
For n = Fn To Cn
 Bt = Replace(Bn, "1", n)
 FileCopy DR & Bn, DT & Bt
Next n
となります。
Fn初期値を2フォルダ作成時を1としています。
どういう意図かと言うとフォルダをつくったときは、受付_PC1から複製しますが、フォルダをつくらなかった場合は、受付_PC1は既に自身のフォルダに存在しているため、複製が必要なのは受付_PC2からとなります。
したがって、状況により繰り返しの開始値(n)を変える必要があります。
人間的に考えると分かりきったことなのでしょうが、相手がExcelさんだと仕方のないことなのでご理解ください。
また、Cnは数値でなければならず、文字が入っていた場合はエラーとなりますが、冒頭の「On Error GoTo Ex」により後述のラベルExに飛ばされます。

繰り返しの内容FileCopy DR & Bn, DT & Btは、自身のFolderにある受付PC1を目的のFolder(DT)にBtの名前でCopyするための構文です。
BtをBt = Replace(Bn, "1", n)とすると、繰り返しの中でBook名「受付_PC1.xlsm」の1の部分がnに置き換えられるので1回目は「受付_PC1.xlsm」、2回目は「受付_PC2.xlsm」、3回目は・・・となります。

最後に修了メッセージを表示して
 MsgBox "   受付用Bookを複製しました。" _
 , 0 + 64, "受付用Book                 njun264
Exit subで一旦処理を終了します。

それから、エラー回避処置を組み込みます。
Exit subの次の行にラベルEx:を置くと、エラーが発生したときだけここに飛び込んできます。
ここで考えられるエラーは、Cn文字(数値以外)が入力されたときと新たにつくるフォルダ(Cells(10, "G")の値)が既に存在しているときです。
また、万一に備えて複写元の「受付_PC1.xlsm」がない時も加えておきましょう。
このようなエラーはエラーコード(Err)で返されるので、そのコードに応じた処理をつくります。
今回はいずれの場合も、エラー表示を出して操作員に対処を委ねます。

Cnの文字はErr=13、フォルダ既存はErr=75、複写元がない時はErr=53となっているので、
If Err = 13 Then
 MsgBox "   数量に誤りがあります。" & Chr(13) _
    & "   2以上の整数を入力してください。" _
    , 0 + 16, "受付用PC_Setup               njun264"

If Err = 75 Then
 MsgBox "   新規Folder「" & Cells(10, "G") & "」は既に存在しています。" & Chr(13) _
    & "   名前を変えてください。" _
    , 0 + 16, "受付用PC_Setup               njun264"

If Err = 53 Then
 MsgBox "   複写元の「受付_PC1.xlsm」が見つかりません。" & Chr(13) _
    & "   受付_PC1.xlsmを復元してください。" _
    , 0 + 16, "受付用PC_Setup               njun264"
とすれば、操作員にエラーの状況と対処方が伝わります。

以上で初期の目標は達成しましたが、欲を出してついでにショートカットまで作ってもらうことにします。
まず、前提として「Windows Script Host Object Model」にCheck を付ける必要があります。
唐突に言われても理解できないと思いますので、以下の手順で操作してください。
VBAエディタのツールをクリックして、参照設定を選択

参照設定

表示される一覧表から「Windows Script Host Object Model」を探してCheckをつけてください。

Windows Script Host Object Modelにチェック

ここから、再びコーディングに戻って
Procedure名を「SCG」としてSub SCG(DT) から始めます。
 DTは前述のProcedure複製」でつくったフォルダ名をParameterとして受け取り、処理を進めます。
Set WS = CreateObject("WScript.Shell") でWshShellオブジェクトを作成し
当該フォルダにあるBookのうち、名前にPCが含まれるものすべてにショートカットをつくります。
Buf = Dir(DT & "¥*PC*.xlsm")
Do While Buf <> ""
 SP = DT & "¥" & Replace(Buf, ”xlsm","lnk")
 With WS.CreateShortcut(SP)
  .TargetPath = DT & Buf 'ShortcutのLink先
  .Save 'Shortcutの保存
 End With
 Buf = Dir()
Loop
とすると、指定したすべてのBookにSPの名前のショートカットが作成されます。

すべてのショートカットをつくり終えたら
Set WS = NothingでObjectをClearして
End SubでProcedureの終わりです。
Procedure「複製」でコーディングしたNext nとMsgBoxの間に
SCG DT を入れると、Procedure「複製」で複製したBookにショートカットをつくって、終了メッセージを表示する一連の処理が完了します。

参考までに完成形は以下のとおりです。

Sub BC()
On Error GoTo Ex

'**Default
    DR = ThisWorkbook.Path & "\"  '自身の居場所(Path)
    Fn = 2                        '複製開始指標

'** Folder作成
    If Cells(10, "G") <> "" Then          '複製場所に入力があったとき
       MkDir DR & Cells(10, "G"): Fn = 1  'Folder作成後Fnを1にする
    End If

'** Book複製
    Bn = "受付_PC1.xlsm"
    DT = DR & Cells(10, "G") & "\"   '複写先Folder(Path)

    Cn = Cells(12, "G")  '複製数量
    If Cn < 2 Or Cn = "" Then Cn = "NG"

    For n = Fn To Cn     '複製繰り返し(Folder作成時は1からその他は2から始める)

      Bt = Replace(Bn, "1", n)   '新しいBook名
      FileCopy DR & Bn, DT & Bt  '**** 複製の構文 今回のMain ****
                                 'Copy元のFile居場所&File名,Copy先のFile居場所&File名
    Next n

    SCG DT  '**** Shortcut作成Procedure **** ついでにショートカットも作る

    MsgBox "   受付用Bookを複製しました。" _
          , 0 + 64, "受付用Book                 njun264"

Exit Sub
Ex:
    If Err = 13 Then MsgBox "   数量に誤りがあります。" & Chr(13) _
                          & "   2以上の整数を入力してください。" _
                          , 0 + 16, "受付用PC_Setup                   njun264"

    If Err = 75 Then MsgBox "   新規Folder「" & Cells(10, "G") & "」は既に存在しています。" & Chr(13) _
                          & "   名前を変えてください。" _
                          , 0 + 16, "受付用PC_Setup                   njun264"
    
    If Err = 53 Then MsgBox "   複写元の「受付_PC1.xlsm」が見つかりません。" & Chr(13) _
                          & "   受付_PC1.xlsmを復元してください。" _
                          , 0 + 16, "受付用PC_Setup                   njun264"

End Sub
Sub SCG(DT) 'Shortcut作成

   '*** マクロ>ツール>Windows Script Host Object ModelにCheck ***
    Set WS = CreateObject("WScript.Shell")  'WshShellオブジェクトを作成

   '*** Folder内のBookを検索 ***
    Buf = Dir(DT & "\*PC*.xlsm")
    Do While Buf <> ""

       SP = DT & "\" & Replace(Buf, "xlsm", "lnk")  'Shortcut作成Folder&Shortcut名

       With WS.CreateShortcut(SP)
           .TargetPath = DT & Buf           'ShortcutのLink先
           .Save                            'Shortcutの保存
       End With

       Buf = Dir()

    Loop
    Set WS = Nothing

End Sub

実行例は以下のとおりとなります。

入力項目
「複製ボタン」クリック後の結果

入力項目により、新しいFolder「研修受付」がつくられてその中に「受付PC_1」~「受付PC_5」とそれぞれのショートカットが作成されます。
このように、File(Book)の複製と、ショートカットの作り方を応用すると、手でコピペしてFileme名を変えて、これを何度か繰り返して・・・。といった煩わしさから開放されるので、是非お試しください。

今回も最後までご覧いただき、ありがとうございました。

この記事が気に入ったらサポートをしてみませんか?