こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

VBScriptでExcel(インデックスが…)

昨日も質問をしたばかりで、自分でも情けないのですが…
(すみません、2つ分からないことがあります。)

VBScriptでExcelのファイルの中身を
別のファイルにコピーするプログラムを作りました。

見にくい変数名で申し訳ないのですが、
これを実行すると、17行目で
「インデックスが有効範囲にありません」
というエラーメッセージが出て止まってしまいます。

しかし、ここで「Set」しているファイルは
「Original.xls」というファイルなのですが、
シートは20個あります。

この20個という数は、絶対にあり得ない数で、
読み込み側のファイルのシートは最大で17個ですので、
数が足りないはずはありません。

だいたい、「インデックス…」というのは配列変数と思って
処理しているのでしょうか?

何より、プログラムの最初の方に
「On Error Resume Next」を置くと、
このプログラムの所期の目的である、

読み込んだファイルの中身を
「Original.xls」にペースとして
ファイル名をかえて保存する

というのは実現できています。

2つ目の問題は、
22行目から24行目で
「Original.xls」の不要なシートを削除しているのですが、
途中に「MsgBox」を置いて、
「s」や「i」の値を調べてみても問題はないのに、
シートが1つしか残りません。

例えば、読み込んだファイルのシートの数が3なら
「s + 1 = 4」ですから、この「For~Next」ループは
「4~20」までの17回実行され、
その間、常に4番目のシートを削除し続け、
結果として、必要な1~3のシートが残るはずなのですが、
常に19個削除されてしまいます。

本来は、「Original.xls」のシートの数は1つにしておいて、
必要な数だけ、その1つのシートをコピーで増やしたかったのですが、
それも分からず、仕方なしにこんなやり方をしました。

やはり、そのやり方でないと、ダメなのでしょうか?

以上、ややこしい質問で申し訳ないのですが、
お分かりの方がおられましたら、お教えください。

Option Explicit '01
Dim d, i, s, t, u, v, w, x, y, z '02
Set t = CreateObject("Scripting.FileSystemObject") '03
Set u = t.GetFolder(".") '04
Set v = CreateObject("Excel.Application") '05
Set w = v.Workbooks.Open(u & "\Result\Original.xls") '06
'07
v.Application.DisplayAlerts = False '08
v.Visible = False '09
'10
For Each d In u.Files '11
If t.GetExtensionName(d.Name) = "xls" Then '12
Set x = v.Workbooks.Open(u & "\" & d.Name) '13
s = x.Worksheets.Count '14
For i = 1 to s '15
Set y = x.Worksheets(i) '16
Set z = w.Worksheets(i) '17
z.Name = y.Name '18
y.Range("A1:U55").Copy z.Range("A1") '19
y.Range("AB1:AF55").Copy z.Range("V1") '20
Next '21
For i = s + 1 to 20 '22
.Worksheets(s + 1).Delete '23
Next '24
x.SaveAs(u & "\o_" & d.Name) '25
w.SaveAs(u & "\Result\" & d.Name) '26
x.Close '27
End If '28
Next '29
'30
v.Quit '31
Set z = Nothing '32
Set y = Nothing '33
Set x = Nothing '34
Set w = Nothing '35
Set v = Nothing '36
Srt u = Nothing '37
Set t = Nothing '38
'39
MsgBox("Finished") '40

よろしく、お願い致します。

投稿日時 - 2012-01-17 11:29:23

QNo.7249599

困ってます

質問者が選んだベストアンサー

実際に動きをみていませんが、ソースをざっと眺めて気付いたのが……
22~24行で、開いたOriginal.xlsの不要なシートを削除していますよね。
そのあと、別名保存していますが、Original.xls自体を開きなおして居ませんので、次のファイルを処理する時にシートが足りなくなっているように思えます。
また、23行目の削除ですが、使用する変数はsではなくiではないでしょうか。

投稿日時 - 2012-01-17 12:55:58

お礼

さっそく、ありがとうございます。

「Original.xls」を開いていない!

確かに、そうですね。
原因が分かりました。
ありがとうございました。

自分でプログラムを見ているだけでは
なかなか気付かず、本当にありがとうございました。

なお、最初は
「w.Worksheet(i).Delete」とやったのですが、
これでは例えばシートが3つの場合、
最初に4番目が削除されると、
シートの数が1つ減るので
5番目というのが元々の6番目なので
結果として、偶数番目だけが削除されます。

従って、単純に「i」には出来ないので、
For i = 20 to s + 1 Step -1
も試したのですが、こちらもダメでした。

大変早くご回答頂き助かりました。

投稿日時 - 2012-01-17 13:43:41

ANo.1

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

ANo.1です、

削除の部分ですが、↓この様にしてはいかがでしょう。
For i = 20 to (s + 1) step -1 '22
.Worksheets(i).Delete '23 ←ここ、w.Worksheets… じゃないですか?
Next '24

あと、37行目でsetがsrtになっています。

投稿日時 - 2012-01-17 13:25:57

お礼

すみません!
ありがとうございます。

23行目は、うっかり削除してしまっただけで、
プログラムではちゃんと
「w.Worksheets(s + 1).Delete」
としています。

また同じく、srtもプログラムでは
「Set」としています。

お騒がせしました。

なお、
For i = 20 to s + 1 Step -1
なら、やってみてダメでしたが、
(s + 1)はまだやってませんので
すぐにやってみます。

ありがとうございました。

なお、「w.Worksheets(i).Delete」は
No.1で答えて下さった「mt2008」さんの方に
説明しています。

投稿日時 - 2012-01-17 13:43:38

あなたにオススメの質問