tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトル異なるブックからのワークシート挿入
記事No15950
投稿日: 2014/08/28(Thu) 14:10
投稿者乙さん
開発環境:Windows XP, Visual Studio 6.0 SP6
目標: master.xls に「全社計」というワークシートが存在し、それに続けて
    別のファイル 01.xls のワークシート「01」を挿入すること。
条件:
(1) この操作を行うサーバ(2003サーバ)には Office がインストールされていません。
(2) 実際には挿入対象となるファイルが 40 個ほどありますが、まず 1 個で実現したいです。
(3) 各ファイルのワークシートにはそのワークシート内で完結している計算式が含まれており、
  これらを活かす必要がありますので、ワークシートの挿入を実現したいです。


以下がソースです
---- ここから ----
Dim XL1, XL2 As Object  'Excel Application
Dim WB1, WB2 As Object  'Excel Workbook
Dim WS1, WS2 As Object  'Excel Worksheet

' 新規にExcelを起動する
Set XL1 = CreateObject("Excel.Application")
XL1.Visible = False

Set XL2 = CreateObject("Excel.Application")
XL2.Visible = False

' 既存のファイルを開く
Set WB1 = XL1.Workbooks.Open("D:\work\master.xls")
Set WB2 = XL2.Workbooks.Open("D:\work\01.xls")
' 操作対象となるワークシートを取得
Set WS1 = WB1.Worksheets("全社計")
Set WS2 = WB2.Worksheets("01")
' シートをコピー(全社計の後に 01 を置きたい)
WS1.Copy After:=WS2

'変数の解放とExcelの終了
Set WS1 = Nothing
Set WS2 = Nothing
WB1.Close saveChanges:=True
WB2.Close
Set WB1 = Nothing
Set WB2 = Nothing
XL2.Quit
XL1.Quit
Set XL2 = Nothing
Set XL1 = Nothing
---- ここまで ----

これを実行すると、

実行時エラー '1004':
Worksheet クラスの Copy メソッドが失敗しました。

と出てしまい、ワークシートの挿入ができません。
WS1.Copy After:=WS2

WS2.Copy After:=WS1
にしても同じメッセージが出てきます。

この操作は手作業でやれば何とかなるのですが、いかんせん、ファイルの
個数が多いのと、将来的にはバッチ処理で夜中に作業させて、朝には
ファイルが使えるようになっている…という状態にするのが理想です。


類似の内容で苦しんでいる方もいらっしゃるのではないかと思い、
投稿させていただきました。
よろしくお願いいたします。

[ツリー表示へ]
タイトルRe: 異なるブックからのワークシート挿入
記事No15951
投稿日: 2014/08/28(Thu) 16:01
投稿者VBレスキュー(花ちゃん)
> Dim XL1, XL2 As Object  'Excel Application
> Dim WB1, WB2 As Object  'Excel Workbook
> Dim WS1, WS2 As Object  'Excel Worksheet

参照設定せずに使用するなら
> WS1.Copy After:=WS2
Excel の定数は使用できません、どこかに宣言していますか?
http://www.hanatyan.sakura.ne.jp/vbhlp/Excel01.htm

http://www.hanatyan.sakura.ne.jp/vb6/excel01.htm

[ツリー表示へ]
タイトルRe^2: 異なるブックからのワークシート挿入
記事No15953
投稿日: 2014/08/28(Thu) 16:17
投稿者魔界の仮面弁士
> 参照設定せずに使用するなら
> Excel の定数は使用できません、どこかに宣言していますか?

提示されたコードには、定数が使われている箇所は無さそうですね。

[ツリー表示へ]
タイトルRe: 異なるブックからのワークシート挿入
記事No15952
投稿日: 2014/08/28(Thu) 16:16
投稿者魔界の仮面弁士
> (1) この操作を行うサーバ(2003サーバ)には Office がインストールされていません。

実行環境に Excel がインストールされていない場合、
「CreateObject("Excel.Application")」が失敗します。

Excel をインストールするか、
Excel の有無に依存しない他の方法を採用してください。


> Set WB1 = XL1.Workbooks.Open("D:\work\master.xls")
> Set WB2 = XL2.Workbooks.Open("D:\work\01.xls")
(中略)
> WS1.Copy After:=WS2

WB1 は XL1 上で開き、
WB2 は XL2 上で開いていますよね。


実際に手作業で操作する場合もそうですが、
『Excel.exe を1つ起動し、その中で 2 つのブックを開く』場合はブック間のコピーができますが、
『Excel.exe を2つ起動し、それぞれでブックを開く』場合には、ブック間のコピーはできません。

[ツリー表示へ]
タイトルRe^2: 異なるブックからのワークシート挿入
記事No15954
投稿日: 2014/08/28(Thu) 17:17
投稿者乙さん
VBレスキュー(花ちゃん) さん
魔界の仮面弁士さん
お二方とも素早い反応ありがとうございました。助かりました。

> > (1) この操作を行うサーバ(2003サーバ)には Office がインストールされていません。
>
> 実行環境に Excel がインストールされていない場合、
> 「CreateObject("Excel.Application")」が失敗します。
>
> Excel をインストールするか、
> Excel の有無に依存しない他の方法を採用してください。

…とのことですので、サーバに Excel をインストールしようと思います。

> > Set WB1 = XL1.Workbooks.Open("D:\work\master.xls")
> > Set WB2 = XL2.Workbooks.Open("D:\work\01.xls")
> (中略)
> > WS1.Copy After:=WS2
>
> WB1 は XL1 上で開き、
> WB2 は XL2 上で開いていますよね。
>
>
> 実際に手作業で操作する場合もそうですが、
> 『Excel.exe を1つ起動し、その中で 2 つのブックを開く』場合はブック間のコピーができますが、
> 『Excel.exe を2つ起動し、それぞれでブックを開く』場合には、ブック間のコピーはできません。
全く仰られるとおりです。
そこで、修正を加えて当初の希望通りの目的を果たせたので、修正したソースを掲載します。
元々の WB1 に該当する master.xls が読み込み専用で開かれてしまっていて、このファイルには
保存できなかったので、別ファイルに保存する形になっていますが…

なお、挿入するワークシートを 1 つから 2 つにしてみました。
あとは私の調整次第です。

---- ここから ----
Dim XL1 As Object            'XL2 は不要なので宣言しない
Dim WB1, WB2, WB3 As Object  'WB3 を追加
Dim WS1, WS2, WS3 As Object  'WS3 を追加

' 新規にExcelを起動する
Set XL1 = CreateObject("Excel.Application")
XL1.Visible = False

' 【修正】以下は不要になった
'Set XL2 = CreateObject("Excel.Application")
'XL2.Visible = False

' 既存のファイルを開く
Set WB1 = XL1.Workbooks.Open("D:\work\master.xls")
' 【修正と追加】XL2 で開くのではなく、同一の XL1 上で開く
' 同じ理由で XL1 上で WB3 を開く
Set WB2 = XL1.Workbooks.Open("D:\work\01.xls")
Set WB3 = XL1.Workbooks.Open("D:\work\02.xls")
' 操作対象となるワークシートを取得
Set WS1 = WB1.Worksheets("全社計")
Set WS2 = WB2.Worksheets("01")
' 【追加】
Set WS3 = WB3.Worksheets("02")
' シートをコピー(全社計の後に 01 を置きたい)
' 【修正】下記は間違い
'WS1.Copy After:=WS2
' 【修正】WS1 の後に WS2 と WS3 を挿入する
WS2.Copy After:=WS1
WS3.Copy After:=WS1

' 【追加】シートを別名保存
WB1.SaveAs "D:\work\master_total.xls"

'変数の解放とExcelの終了
Set WS1 = Nothing
Set WS2 = Nothing
' 【追加】
Set WS3 = Nothing
WB1.Close saveChanges:=True
WB2.Close
' 【追加】
WB3.Close
Set WB1 = Nothing
Set WB2 = Nothing
' 【追加】
Set WB3 = Nothing
' 【修正】以下は不要になった
' XL2.Quit
XL1.Quit
' 【修正】以下は不要になった
' Set XL2 = Nothing
Set XL1 = Nothing
---- ここまで ----

[ツリー表示へ]
タイトルRe^3: 異なるブックからのワークシート挿入
記事No15955
投稿日: 2014/08/28(Thu) 18:49
投稿者魔界の仮面弁士
> 元々の WB1 に該当する master.xls が読み込み専用で開かれてしまっていて、
.Workbooks.Open 時には、ReadOnly 指定されていないように見えますが、
同じファイルを別のアプリケーションでも開いているということでしょうか?



> Dim WB1, WB2, WB3 As Object  'WB3 を追加

この場合、
 Dim WB1 As 既定の型, WB2 As 既定の型, WB As Object
という意味になります。
(特に指定が無い場合、既定の型は Variant です)

すべてを As Object の意味にしたいのであれば、
そのモジュールの先頭に『DefObj W』の宣言を加えておくか、もしくは
Dim WB1 As Object, WB2 As Object, WB3 As Object
のように、個別に宣言する必要があります。


> Set XL1 = CreateObject("Excel.Application")
サーバー上で実行させるのであれば、DisplayAlerts プロパティも設定しておくことをお奨めします。
サーバー上で警告や確認が表示されたままになっても困りますしね。


> XL1.Visible = False

ちなみに、システムのプロパティの
 [詳細設定] - [パフォーマンス] → [設定]
  → [詳細設定] - [プロセッサのスケジュール]
の設定によっては、非表示にすると処理速度が低下する場合があるようです。

[ツリー表示へ]