以前別のカテゴリで質問したのですが、そちらでは解決出来なかったので、こちらで改めて質問します。
下記のマクロで、一つのブックからSheet1だけをコピーして来て、少し処理をし、元のブックを閉じるというもので、ブックの数は多くて3000程、少ない時は300位です。
で、このマクロだと900位までですと最後まで行くのですが、それを超えるとリストが95位で止まってしまいます。
自宅で別データを作ってやってみるとうまくいきました。
コピー元のブックにはテキストデータのみで、200文字から500文字程度の大きさしかありません。
ファイル名も50文字程度の物を全部20文字程度まで短くしてもみましたが、ダメでした。
どうかお知恵をお貸しください。

Sub ★1★ブックの結合()
Dim sFile As String
Dim sWB As Workbook, dWB As Workbook, aWB As Workbook
Dim dSheetCount As Long
Dim i As Long
Dim SOURCE_DIR As String

'エクセルデータに変換されたファイルのあるフォルダを選択します。
MsgBox "エクセルに変換されたデータのフォルダを選択"
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show = True Then
SOURCE_DIR = .SelectedItems(1) & "\"
End If
End With

Application.ScreenUpdating = False

'指定したフォルダ内にあるブックのファイル名を取得
sFile = Dir(SOURCE_DIR & "*.xls")

'フォルダ内にブックが無ければ終了
If sFile = "" Then Exit Sub

'集約用ブックを作成
Set dWB = Workbooks.Add

'転記マクロの中のDMリストシートをコピーする
Workbooks("転記用マクロ.xlsm").Worksheets("DMリスト").Copy Before:=dWB.Worksheets("Sheet1")
Application.DisplayAlerts = False
Worksheets(Array("Sheet1", "sheet2", "sheet3")).Select
ActiveWindow.SelectedSheets.Delete
Application.DisplayAlerts = True

'集約用ブック作成時のシート数を取得
dSheetCount = dWB.Worksheets.Count

Do
'コピー元のブックを開く
Set sWB = Workbooks.Open(Filename:=SOURCE_DIR & sFile)

'コピー元のsheet1を集約用ブックにコピー
sWB.Worksheets("sheet1").Copy After:=dWB.Worksheets(dWB.Sheets.Count)

シート転記

'コピー元ファイルを閉じる
Application.DisplayAlerts = False
sWB.Close
Application.DisplayAlerts = True

'セルA2の名前を変更する


'シート名をセルA2の値に変更
'ActiveSheet.Name = Range("A2").Value


'次のブックのファイル名を取得
sFile = Dir()
Loop While sFile <> ""

'集約用ブックを保存する
'dWB.SaveAs Filename:=DEST_FILE


Application.ScreenUpdating = False


End Sub

このQ&Aに関連する最新のQ&A

A 回答 (5件)

http://oshiete.goo.ne.jp/qa/8750372.html


例えば、30ファイルあっても10ファイルしか読み込まれない事があり、
エラーメッセージもない、何事もなく終了するが10ファイルしか処理されていない、
常に発生する訳ではなく、マシンが変われば同じデータでもOKだったり、
データが少し変わればOKだったりする。
なので、昨日までOKだったのに、今日データが変わった為、急にダメになったりする。
もし、10ファイル目で発生した場合、何度実行しても必ず、10ファイル目までしか処理されない。
そのファイルがおかしいかと思い、その前後の2~3ファイルを削除しても、
やっぱり、10ファイル目(さっきとは違うファイル)までしか処理されない、
という恐ろしいバグがExcel VBAにありますが、それじゃないですかね?

While文などのループの中に、ワークブックのオープンがあると、
何度目かでオープンが実行されず、エラーなしでスルンと終わります。

回避方法は、Open 文の前に DoEvets の1行を書く事。
だいたいこれで直りますが、これで直らなかったマクロもあったので、
Open 文の後ろにも DoEvets の1行を書いて、前後を DoEvets ではさむと直りました。
安全(?)の為、前後をはさんでおいた方が良いと思います。

こんな感じ:
DoEvents
Workbooks.Open aaa
DoEvents

かなり前(1年くらい?)にハマりググりまくったところ、ほとんど情報はなかったですが、
1人だけ、自分の質問に「直った」と自己回答している方がいて、Open文の前にDoEvetsをつけたら直ったそうです。
半信半疑で真似たら私も直りました。
何故、これで直るのかはわかりませんが、DoEvetsを外すと見事に再現し、DoEvetsではさむとピタッと直ります。

ググりまくった際、とても情報が少なく、こんなに顕著に再現するのに、
何故、情報が少ないのかは不思議に思いました。
    • good
    • 13
この回答へのお礼

ご回答があった中で一番単純そうでしたので、一番初めに試した所、本当に何の問題もなく最後まで処理して完了しました。
1700でも1400でも大丈夫でした!
どこを探しても見つからなかった答えがあっさりと解決しました。
DoEventoの事も全く知らなかったので、勉強になりました。
本当にありがとうございました。

お礼日時:2014/09/18 10:41

こんな事を書くと答えにならないかもしれませんが。


うまくいった時の結果は、シート数が3000枚ですよね。
エクセルのシート最大数はヴァージョンにもよりますが
多くはメモリーで決まるようです。
メモリーなので、貼り付けているシートの内容も影響します。
つまり、やろうとしていることに無理があると思います。

試しに、シートを追加して、内容をコピーするVBAを実行してみましたが
途中途中で挙動不審になり、終了したシートを確認していったら
102枚目に、編集できないシートがありました。

考え方ですが、他のブックの内容を、データとして
一枚のシートへひたすら縦方向へ追加していく方法を検討してみてください。

エクセルでシートを増やしていくデータの管理はパソコンに負担ですし
その手のデータでは集計もグラフも作れないでしょう。
    • good
    • 1
この回答へのお礼

回答をありがとうございました。
このマクロはそのような処理をしながら進んで行くようにしていますが、何故か途中で終わってしまうので、悩んでいました。
また何かありましたらどうぞよろしくお願いします。

お礼日時:2014/09/18 10:35

>何行目で止まるかはわかりません。


>数千のブックがあるのに、出来上がったリストは
>90代程度しか出来ていなくて、エラーも何もなく終わってしまいます。

そもそもプログラムで問題が起きたときにまず最初に確認すべきことは、プログラムが正常終了しているのか異常終了しているのか確認することです。

「Do」の前に
「Debug.Print("ループ開始")」を

「Loop While sFile <> ""」の後ろに
「Debug.Print("ループ終了")」を書いて実行してみてください。

するとイミディエイトウインドウにメッセージが表示されます。
もしも「ループ開始」しか表示されないようであれば処理が途中で止まっているということです。

ループ内でもメッセージを出力する処理を何個所か書いて、どこで終了しているのか特定しましょう。


もしも「ループ終了」が表示されるのなら、おそらく処理は正常終了しています。95ファイル処理して終了するのなら、「対象ファイル」は物理的に95しか存在していないという可能性もあります。

Dirコマンドでオプション無指定で対象になるのは標準ファイルだけです。読み取り専用属性等のファイルは対象になりません。それが原因かもしれません。もしここが原因なら、すべてを標準ファイルにするか、プログラムを以下のように変更してみるといいと思います。

「sFile = Dir(SOURCE_DIR & "*.xls", 1)」とか
「sFile = Dir(SOURCE_DIR & "*.xls", 3)」とか。
    • good
    • 0
この回答へのお礼

丁寧なご回答をありがとうございました。
回答をいただいた中で、簡単な物から試してみましたら、他の方の回答であっさりと解決してしまいました。
また躓きましたらこちらも次回参考にさせていただきますね。
どうぞ今後ともよろしくお願いします。

お礼日時:2014/09/18 10:43

前の質問へのリンクですね。


何らかの経過があるならば、と思ったので。

何とも不思議な状態ですね。
時間がかかっても
> Application.ScreenUpdating = False
はコメントアウトしておくとか。

上手く行かない時、他のウインドウ操作したりせずに、じっと待つ。
そのためにはスクリーンセイバー・省電力は解除

> 'コピー元ファイルを閉じる
> Application.DisplayAlerts = False
> sWB.Close
> Application.DisplayAlerts = True
クローズした後
'コピー元ファイルを閉じる
Application.DisplayAlerts = False
sWB.Close
Set sWB = Nothing ’追加してみるとどうなります?
Application.DisplayAlerts = True



あと、気になったのがココ
> '集約用ブックを保存する
> 'dWB.SaveAs Filename:=DEST_FILE
本番ではコメントアウトを解除してありますか?
    • good
    • 0
この回答へのお礼

素早いご回答をありがとうございました。
確かに一連の経過がありました。質問が杜撰で申し訳ありませんでした。
今後は過去の質問とのリンクも合わせて投稿させていただきます。
他の方の回答で解決しましたので、また躓いた時に参考にさせて下さい。
本当にありがとうございました。

お礼日時:2014/09/18 10:47

> それを超えるとリストが9 5位で止まってしまいます。


「どこの行で」「どう」止まる?
・エラーメッセージは出ますか?出るなら何と書いてますか?どこの行ですか?
・何もエラーは出ないが目的の結果が得られない?

> 自宅で別データを作ってやってみるとうまくいきました。
・データによって、うまく行く/行かないがあるなら、両方で同じデータを用いることができますか?

続きの質問なら、せめてアンカーを付けてはどうでしょう?

この回答への補足

早速ありがとうございます。
アンカーなるものがちょっとわからないのですが、以前した質問へのリンクということでしょうか?
その時の質問はレスが付かなかったため、削除しました。

何行目で止まるかはわかりません。
数千のブックがあるのに、出来上がったリストは90代程度しか出来ていなくて、エラーも何もなく終わってしまいます。
大体いつも同じ位の所で終わるようですが、200位の時でも最後までリストを作ってくれることもあります。
自宅にデータを持って帰ることは出来ないので、大体似たような物を作り、コピーしてきた後の動きも少し単純にしています。
ですが以前、シートをコピーした後の動きをつけずに、ただひたすらシートをコピーしてくるだけのものを作ってみたのですが、その時も同じように90過ぎ位で終了してしまいました。
データが大きくなってしまうのが原因かと思い、いっそのことコピーした後の動きを一緒にして、データが大きくならないようにしてみたのですが、やっぱり同じことでした。

補足日時:2014/09/11 20:36
    • good
    • 0
この回答へのお礼

大変助かりました。
ありがとうございました。

お礼日時:2014/09/18 10:47

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QEXCEL VBA「Application.DisplayAlerts」について

Application.DisplayAlerts = False
XXXXXXXX
Application.DisplayAlerts = True

で、確認画面を出さずにXXXXXXXXの処理をすることができますが、
その確認画面に、いくつかの選択ボタンがある場合、
確認画面を出さずに、かつ、任意のボタンを押した状態で処理を進めさせるには、どのようにすればよいのでしょうか?

そのまま Application.DisplayAlerts を使うと、確認画面は出ないものの
デフォルトのボタン(フォーカスがあるボタン)が押された状態で、
処理が進められてしまうようです。

Application.DisplayAlerts を使わない別な方法でもかまいません。
ご存知の方、ご教授いただけると幸いです。
よろしくお願いします。

Aベストアンサー

開くときに確認ダイアログが出るのは「読み取り専用」ではなく「読み取り専用推奨」だと思いますがそれはさておき。
#「読み取り専用」なら選択出ません

http://msdn.microsoft.com/ja-jp/library/microsoft.office.interop.excel.workbooks.open(VS.80).aspx
にあるとおりOpenメソッドでReadOnlyパラメータをFalseに設定してやればいいような。

ついでに、このダイアログを出さないだけならApplication.DisplayAlertsではなくWorkbooks.OpenでIgnoreReadOnlyRecommendedをTrueにすればよさそうです。

QMicroSoft BasicのDim文とVisualBasicのDim文の違い

私が20年前にMicroSoft Basicを使っていたときは、DIM文はDIMENSIONの略で配列型変数の宣言に使っていました。

最近VisualBasicの勉強を始めたのですが、変数の宣言はすべてDim文になっており、昔のMS BasicのDim文と意味合いが変わっているのに驚いています。

ここで質問させてください。
・なぜ配列を意味するDimension文が変数の宣言なのか?
・どのバージョンのBasicからDim文の意味が変わったのか?

私が使用していたのはNEC N-Basic,N-88Basic,N-98Basicです。

Aベストアンサー

VISUAL BASIC のDimは ディメンジョンの略です。
私の経験ではVB2.0時代からありました。

配列0を考えた場合変数とおなじであるからだとおもいます

Qなぜ「Workbook」ではなく「Workbook

なぜ「Workbook」ではなく「Workbooks」なのでしょうか?
エクセルVBAについて教えてください。

ファイルのタイトルバーのところに、文字を入れたくてVBAコードを調べていたら
Workbooks.Application.Caption = "タイトル"
と言うコードが出てきました。

このコードでやりたいことが行えるので問題ないのですが、
なぜファイル(ブック)は一つしか開いてないのに、「Workbooks」なのでしょうか?

Aベストアンサー

■Application クラス
・EXCEL本体の親ウインドウ側のクラス
・主なプロパティとして
Caption EXCEL本体のタイトルバーの文字列
Visible EXCEL本体を表示/非表示
TOP,LEFT,WIDTH,HEIGHT EXCEL本体の位置や大きさを変更する
Workbooks
EXCEL 本体で開いている ブック(複数)のリスト

■Workbooks クラス
・Workbook クラスのコレクションクラス
・EXCEL を親ウインドウとして ブック(workbook)を複数開く事が出来るためそのリストクラス
・主なプロパティ、メソッドとして
Add 新たなブックを表示する
Open ブックを開く
Item Workbook を選択する
Application 親元の EXCEL

■Workbook クラス
・Workbook ブックのクラス
・主なプロパティ、メソッドとして
Save ブックを保存する
Application 親元の EXCEL
WorkSheets
 ブック内にあるシート(複数)のリスト

■WorkSheets クラス
・WorkSheet クラスのコレクションクラス
・主なプロパティ、メソッドとして
Add 新たなシートを作成する
Item WorkSheet を選択する
Application 親元の EXCEL

■WorkSheet クラス
・WorkSheet シートのクラス
・主なプロパティ、メソッドとして
Range 各セル単位のクラス
Application 親元の EXCEL



だいたいのEXCELクラスの位置づけ(雰囲気)はこんな感じ

■Application クラス
・EXCEL本体の親ウインドウ側のクラス
・主なプロパティとして
Caption EXCEL本体のタイトルバーの文字列
Visible EXCEL本体を表示/非表示
TOP,LEFT,WIDTH,HEIGHT EXCEL本体の位置や大きさを変更する
Workbooks
EXCEL 本体で開いている ブック(複数)のリスト

■Workbooks クラス
・Workbook クラスのコレクションクラス
・EXCEL を親ウインドウとして ブック(workbook)を複数開く事が出来るためそのリストクラス
・主なプロパティ、メソッドとして
Add 新たなブックを表示する
Open ブッ...続きを読む

QDim x As Integer = 0

いつもお世話になっております。

只今、本に記載してあるソースコードを手入力しています。
標記のように入力したら、『コンパイルエラー 修正候補:ステートメントの最後』というエラーが出ました。

(1)このエラーは無視してもよいのでしょうか?
(2)そもそも、変数の宣言文の後ろに=0をつけている意味がわかりません。当方VB初心者です。

よろしくお願いいたします。

Aベストアンサー

この点は(変数の宣言と初期化は)言語による、と考えるべきです。
この質問は何の質問か。
VB系統らしいことは判るが
VB以外のBASIC
VB6
VBA
VB.NET系統
のどれか質問に書くべき。質問者は経験が無くて、視野がそこまで行かないのかも知れないが。
ーーー
VBAでは(多分VBでも同じ。テスト環境がないので)
Sub test01()
Dim x As Integer
x = 0
MsgBox x
End Sub
はOK
ーー
Sub test01()
Dim x As Integer =0
MsgBox x
はDim x As Integer =0
と入力した段階でエラー。
http://www.bunsugi.ed.jp/vba4graduate/vba_hensuusyokika.htm
ーーー
定数のConstであればこういう書き方はOK
Sub test01()
Const x As Integer = 0
MsgBox x
End Sub
ーーー
VB.NETでは、OK
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
Dim x As Integer = 10
MsgBox(x)
End Sub
ーー
Javaでは可能であるようです
http://msugai.fc2web.com/java/var2.html
ーーーーー
>ろに=0をつけている意味がわかりません
宣言と同時に値を与える=初期化する

この点は(変数の宣言と初期化は)言語による、と考えるべきです。
この質問は何の質問か。
VB系統らしいことは判るが
VB以外のBASIC
VB6
VBA
VB.NET系統
のどれか質問に書くべき。質問者は経験が無くて、視野がそこまで行かないのかも知れないが。
ーーー
VBAでは(多分VBでも同じ。テスト環境がないので)
Sub test01()
Dim x As Integer
x = 0
MsgBox x
End Sub
はOK
ーー
Sub test01()
Dim x As Integer =0
MsgBox x
はDim x As Integer =0
と入力した段階でエラー。
http://www.bunsug...続きを読む

QLabel2.visible=false

任意の関数式を入れるとグラフを描くプログラムを作りました。表示するのに時間がかかる(といっても1秒程度ですが)ので「計算中!」と赤で表示させ、グラフが描き終わると消したいと思い、グラフ開始時にLabel2.Visible=True、終了時にLabel2.Visible=Falseを付けましたが、思惑通りには行きません。何故でしょう。おわかりになる方、教えてください。

Aベストアンサー

.NET以降,DoEvents (System.Windows.Forms.Application.DoEventsメソッド) の使用は推奨されません。
DoEventsはVB6までやVBAのような,マルチスレッドが扱えない言語における代替策でしかなく,
長時間かかる処理 (だいたい50ms:WinRT APIにおける非同期処理の目安) を超えるようであれば,その処理はバックグラウンドスレッドで処理すべきです。

VB 2005以降であれば,BackgroundWorkerコンポーネントをFormに配置し,
・Label2.Visible = False後,配置したBackgroundWorkerのRunWorkerAsyncメソッドを呼び出す
・グラフの点の計算をBackgroundWorkerのDoWorkイベントに記述する。
※このイベントの中で,Formのコントロールやコンポーネントに触ることができないので注意して下さい。
・BackgroundWorkerのRunWorkerCompletedイベントで,グラフの描画やLabel2.Visible = Trueを行う。
という方法で処理を行います。
# VB 2012以降で.NET 4.5以降をターゲットとする場合では,Async/Awaitを使う方法が推奨されます。

ref) MSDN: 方法 : バックグラウンドで操作を実行する
http://msdn.microsoft.com/ja-jp/library/hybbz6ke.aspx

.NET以降,DoEvents (System.Windows.Forms.Application.DoEventsメソッド) の使用は推奨されません。
DoEventsはVB6までやVBAのような,マルチスレッドが扱えない言語における代替策でしかなく,
長時間かかる処理 (だいたい50ms:WinRT APIにおける非同期処理の目安) を超えるようであれば,その処理はバックグラウンドスレッドで処理すべきです。

VB 2005以降であれば,BackgroundWorkerコンポーネントをFormに配置し,
・Label2.Visible = False後,配置したBackgroundWorkerのRunWorkerAsyncメソッドを呼び...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報