やりたかったこと
- マクロファイルAのセルをコピーして、マクロファイルBに図として貼り付け
- マクロファイルAのシートをコピーして新規ブックを作成し、シート中のグラフ(参照先:マクロファイルAの別シート)を図に変換
1.のコードの抜粋
'マクロファイルAのセルのコピー
rngMacroFileA.Copy
'マクロファイルBのシートをアクティベート
sheetMacroFileB.Activate
'図として貼り付け
sheetMacroFileB.Pictures.Paste.Select
2.のコードの抜粋
'グラフを画像としてコピー
objChart.CopyPicture
'ペースト
sheetMacroFileB.Paste
問題
必ずではないが、実行時エラー(1004)が発生する。
VBEが開きデバッグモードになるが、再開すると処理が正常に行われる。
調査
下記のサイトを参考にした。
- https://excelshogikan.com/tips/tips151.html
- https://social.msdn.microsoft.com/Forums/ja-JP/e590e461-0c18-4891-89e2-70281f8b0029/12463125221248312503125081254012489123631242512398paste1239512424?forum=vbajp
- https://winactor.com/questions/question/excel%E3%81%AEpaste%E5%A4%B1%E6%95%971004%E5%AF%E7%AD%96/
どうも、クリップボードを介した処理は不安定であるらしい。。。
暫定対応
- DoEvents関数でOSに処理を渡してみる
- Sleep関数でPasteを待ってみる
- 失敗したら3回までリトライするようにエラーハンドリングする
1.のコードの改良版の抜粋 ※2.のコードも同じ改良を施した
'Sleep関数の準備
#If VBA7 Then
'For 64 Bit Systems
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
#Else
'For 32 Bit Systems
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Sub XXX()
(中略)
'エラー回数を初期化
Dim intErrCnt As Integer
intErrCnt = 0
On Error GoTo ERROR_HANDLE
'マクロファイルAのセルのコピー
rngMacroFileA.Copy
'マクロファイルBのシートをアクティベート
sheetMacroFileB.Activate
'★実行時エラー(1004)対応:OSに処理を渡す&Pasteを待ってみる
DoEvents
Sleep (100)
'図として貼り付け
sheetMacroFileB.Pictures.Paste.Select
On Error GoTo 0
(中略)
Exit Sub
ERROR_HANDLE:
'★実行時エラー(1004)対応:エラー3回まではリトライする
intErrCnt = intErrCnt + 1
If intErrCnt <= 3 Then Resume
'更新中のマクロファイルBを保存せずに閉じる
sheetMacroFileB.Parent.Close SaveChanges:=False
MsgBox "処理に失敗しました。" & vbCrLf & _
"XXXボタンを押下し、再度実行してください。"
End
End Sub
結果
処理を3回までリトライするようにしたことで、
実行時エラー(1004)が表示されることは今のところない。
暫くはこれで様子見するか。。。