スタッフブログ

ExcelVBAのクリップボードエラーについて

2025年10月27日 スタッフブログ 平川 開発 

最近はExcelVBAを使用してのツール開発のご依頼が増えてきています。
そんな中、「クリップボードエラー」問題に遭遇することが多くなりました。
 
印刷用にテンプレートを用意し、表示ページ数の分だけテンプレートを読み込んで表示内容をセルに格納するといった処理で、VBAの「Copy」と「Paste」メソッドを使用したいのですが、これらの処理を何度も繰り返すと「クリップボードエラー」が発生します。
 
「別のアプリケーションで使用されているため、コンテンツをクリップボードにコピーできませんでした。このブック内にコンテンツを貼り付けすることは出来ますが、他のアプリケーションでは使用できません。」と表示され、処理中に別のコピー&ペーストができないという問題が発生するようです。
 
ネットで「クリップボードエラー」について調べてみても根本的な解決策は見当たらず、多かったのが「Copy&Pasteを使用せずにコピー元のセル情報をすべて配列に格納して、新しいシートのセルに必要なプロパティを設定する」という意見でした。
 
そこで、以下のような処理を実装してみましたのでご紹介したいと思います。

Set wks = Sheets(“テンプレート”)

xMax = 42
yMax = 40

‘テンプレートの列幅を取得
For lngCol = 1 To xMax
 ReDim Preserve varColWidth(0 To UBound(varColWidth) + 1) As Variant
 varColWidth(UBound(varColWidth)) = wks.Columns(lngCol).ColumnWidth
Next lngCol

‘テンプレートの行高さを取得
For lngRow = 1 To yMax
 ReDim Preserve varRowHeight(0 To UBound(varRowHeight) + 1) As Variant
 varRowHeight(UBound(varRowHeight)) = wks.Rows(lngRow).RowHeight
Next lngRow

‘テンプレートシートより、マージされた各セルのRangeオブジェクトを配列に格納
ReDim objTemplateInfo(0) As Range
strMergeAddress = “”

For lngRow = 1 To yMax

 For lngCol = 1 To xMax

  If wks.Cells(lngRow, lngCol).MergeArea.Address strMergeAddress Then

   Set rng = wks.Range(wks.Cells(lngRow, lngCol).MergeArea.Address)
   ReDim Preserve objTemplateInfo(0 To UBound(objTemplateInfo) + 1) As Range
   Set objTemplateInfo(UBound(objTemplateInfo)) = rng

  End If

  ’次の列のMergeArea.Addressを取得
  strMergeAddress = wks.Cells(lngRow, lngCol).MergeArea.Address

 Next lngCol

Next lngRow

Set wks = Nothing

‘新規シートの追加
Sheets.Add After:=Sheets(Sheets.Count)
Set wks = Sheets(Sheets.Count)

‘列幅の設定
For lngCol = 1 To UBound(varColWidth)
 wks.Columns(lngCol).ColumnWidth = varColWidth(lngCol)
Next n

‘行高さ設定
For lngRow = 1 To UBound(varRowHeight)
 wks.Rows(lngRow).RowHeight = varRowHeight(lngRow)
Next n

‘テンプレートシートから読み込んだ各マージセル情報を新規シートに適用
For n = 1 To UBound(objTemplateInfo)

 ’マージ対象セルのアドレスを取得
 strMergeAddress = objTemplateInfo(n).Address

 ’マージ実行
 wks.Range(strMergeAddress).Merge
 Set rng = wks.Range(strMergeAddress)

 ’マージセルのプロパティ設定
 With objTemplateInfo(n)
  rng.HorizontalAlignment = .HorizontalAlignment
  rng.VerticalAlignment = .VerticalAlignment
  rng.Value = .Value
  rng.ShrinkToFit = .ShrinkToFit
  rng.Interior.Color = .Interior.Color
  rng.Font.Name = .Font.Name
  rng.Font.Size = .Font.Size
  rng.Font.Color = .Font.Color
  rng.Font.Bold = .Font.Bold
  rng.Font.Italic = .Font.Italic
  If .Borders(xlEdgeLeft).LineStyle <> xlNone Then
   rng.Borders(xlEdgeLeft).LineStyle = .Borders(xlEdgeLeft).LineStyle
   rng.Borders(xlEdgeLeft).Color = .Borders(xlEdgeLeft).Color
   rng.Borders(xlEdgeLeft).Weight = .Borders(xlEdgeLeft).Weight
  End If
  If .Borders(xlEdgeTop).LineStyle <> xlNone Then
   rng.Borders(xlEdgeTop).LineStyle = .Borders(xlEdgeTop).LineStyle
   rng.Borders(xlEdgeTop).Color = .Borders(xlEdgeTop).Color
   rng.Borders(xlEdgeTop).Weight = .Borders(xlEdgeTop).Weight
  End If
  If .Borders(xlEdgeRight).LineStyle <> xlNone Then
   rng.Borders(xlEdgeRight).LineStyle = .Borders(xlEdgeRight).LineStyle
   rng.Borders(xlEdgeRight).Color = .Borders(xlEdgeRight).Color
   rng.Borders(xlEdgeRight).Weight = .Borders(xlEdgeRight).Weight
  End If
  If .Borders(xlEdgeBottom).LineStyle <> xlNone Then
   rng.Borders(xlEdgeBottom).LineStyle = .Borders(xlEdgeBottom).LineStyle
   rng.Borders(xlEdgeBottom).Color = .Borders(xlEdgeBottom).Color
   rng.Borders(xlEdgeBottom).Weight = .Borders(xlEdgeBottom).Weight
  End If
 End With

Next n

Set wks = Nothing

テンプレートシートの指定範囲のセルの情報をRangeオブジェクトごと配列に格納し、新シートの各セルをテンプレートと同じになるように結合してフォントや罫線や色などのプロパティを設定する、といった処理です。複数ページにわたる場合は設定するセルのアドレスを計算するという工夫が必要になります。
 
処理中はコピー&ペースト作業をしなければ問題は起きないようですが、そういうわけにもいかないという場合は必要になりそうですね。
 
参考になれば幸いです。