エクセルマクロを使用してエクセルシートからデータを順次読みとり書き込む処理をしていますが時間がかかり困っています。CPUやメモリなどの資源を常に限界まで使用したり、ロジックを工夫したりして大幅にスピードUPしましたがそれでもまだ3日以上かかります。自分の知識、能力ではもう限界です。ここをこうすれば処理が速くなった、という経験や知識をお持ちの方、些細なことでも教えてください、お願いします。(SQLを必要としないデータ、1つのファイルのライン数が多くても4万ラインまで、後で手で編集したり分析ツールが使用しやすいなどの理由でエクセルを使用していますが、ファイル数は5000、サイズは計15Gになります。)またこちらのPC環境はCPU:ペンタ3の866、メモリ:512、OS:2000、エクセル:2000です。

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

A 回答 (2件)

エクセルファイル間のやり取りではなく


テキストファイルを利用したもの
に変えてみてはどうでしょうか。
どのようなデータ、処理か
分かりませんが、必要な項目のデータを
集めるようなものであれば
入力・出力をテキストで行って
1行読む、処理、書き込む、次へ。
結果をエクセルで開く。
シートへのアクセスは
時間のかかるイメージがあるもので。
4万行を表示せず済みます。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
やはりそれが正論でしょうね...少し意固地になっていました。
どの位速くなるかわかりませんが試してみます。

お礼日時:2002/02/16 22:36

まずよくやるのが


ScreenUpdating = False ですが、当然入ってますよね。
あとはCellやRangeの余計なSelectをなくすとか。

それと、Integer型の変数は基本的に使わないほうが良いです。Long型にしましょう。
Windowsの内部処理が32bit(=4byte)で行われていてInteger型の16bit(=2byte)を32bitに変換しながらCodeを実行するためです。
5分くらいかかるマクロが25%速くなった経験があります。 
    • good
    • 0
この回答へのお礼

回答ありがとうございました。
今までIntegerが当たり前、の感覚を持っていました。

お礼日時:2002/02/16 22:19

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

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

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

QEXCEL2000:結合したセルにオートフィルタを使用する場合

質問があります。

以下のようなリスト作成しています。
【リスト】
行 支店名   担当者 業績
1 東京    ●●  1000
2 (↑と結合)▲▲  2000
3 (↑と結合)◆◆  3000
4 大阪    ○○  1000
5 (↑と結合)△△  3000
6 (↑と結合)□□  2000

この場合、支店名の「東京」をフィルタで選択すると、担当者:●●の行(1行目)しか表示されません。

「東京」を選択した際に東京の担当者全員の行(1~3行目)が全て表示されるようにすることは可能でしょうか?

ご回答よろしくお願い致します。

Aベストアンサー

遅くなり申し訳ありません。#1です。
方法は色々ありますが、下記を参考に・・・
A列に”支店名”、B列に”担当者”、C列に”業績”があるとして下記のマクロはD列にA列を参照してばらしています。よってD列をオートフィルタですればよいと思います。
あまり複雑なマクロでは質問者様の他作業に影響もあると思いますので今の現状に限りなく近い方法でのマクロです。

Sub test()
With Worksheets(1)
i = 2
Do While Cells(i, 1).MergeCells = True Or VarType(Cells(i, 1).Value) <> 0
i = i + 1
a = VarType(Cells(i, 1).Value)
a1 = Cells(i, 1).MergeCells
Loop
For j = 2 To i - 1
a = Cells(j, 1).Value
b = Cells(j + 1, 1).Value
If VarType(a) = 8 Then
Cells(j, 4).Value = a
Else
Cells(j, 4).Value = Cells(j - 1, 4).Value
End If
Next
End With

End Sub

遅くなり申し訳ありません。#1です。
方法は色々ありますが、下記を参考に・・・
A列に”支店名”、B列に”担当者”、C列に”業績”があるとして下記のマクロはD列にA列を参照してばらしています。よってD列をオートフィルタですればよいと思います。
あまり複雑なマクロでは質問者様の他作業に影響もあると思いますので今の現状に限りなく近い方法でのマクロです。

Sub test()
With Worksheets(1)
i = 2
Do While Cells(i, 1).MergeCells = True Or VarType(Cells(i, 1).Value) <> 0
...続きを読む

Q複数のエクセルファイルに対してマクロを順次実行する方法

エクセルのマクロについて教えていただきたいです。
以下のような状況なのですが、アドバイスいただけないでしょうか。

・同一フォルダに100個以上の同じ形式のエクセルファイルがある(ファイル名に規則性はなし)
・各ファイルは2つのシートから成り、そのうちの「データ」というシートに対して処理を適用したい
・適用したい処理のマクロは作成済み
なお、適用したい処理というのは、「データ」シートからある値以上のデータの平均を別のエクセルファイル(これは1つのファイル)に記入するという作業で、値を読み込むだけで書き込むことはありません。

このマクロをフォルダ内の全てのエクセルファイルに対して実行したいのですが、可能であれば各エクセルファイルを開かずにマクロを実行したいのです。(100個を越えるファイルを開いたり閉じたりする動作を避けたい)

マクロはしっかりと勉強したわけではなく、ネットから情報を集めつつなんとか作っているレベルで、特にファイルの読み書きがよく理解できていません・・・分かりやすいサイトなどがあればそれも教えていただきたいと思っています。

自分でも上手く説明できていないのはわかりますので、もし必要な情報がありましたら付け加えさせていただきます。
分かる方がいらっしゃいましたらどうぞよろしくお願いいたします。

エクセルのマクロについて教えていただきたいです。
以下のような状況なのですが、アドバイスいただけないでしょうか。

・同一フォルダに100個以上の同じ形式のエクセルファイルがある(ファイル名に規則性はなし)
・各ファイルは2つのシートから成り、そのうちの「データ」というシートに対して処理を適用したい
・適用したい処理のマクロは作成済み
なお、適用したい処理というのは、「データ」シートからある値以上のデータの平均を別のエクセルファイル(これは1つのファイル)に記入するという作業...続きを読む

Aベストアンサー

Dir関数に対しもうひとつの方法として、FSOを使う方法がある。
ーー
Sub test01()
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Dim objfs
Dim objfolder
Dim wb
Set objfs = CreateObject("scripting.filesystemobject")
Set objfolder = objfs.getfolder(CurDir)
MsgBox CurDir
For Each objfile In objfolder.Files
If objfs.getextensionname(objfile) = "xls" Then
MsgBox objfile.Name
Set wb = Workbooks.Open(objfile)
Windows(wb.Name).Visible = False
MsgBox wb.Sheets(1).Range("A1")
'ここで、捕まえた1ブックの処理
wb.Close
Set wb = Nothing
End If
Next
Application.DisplayAlerts = False
Application.ScreenUpdating = False
End Sub
ーー
上記のCurdirは
エクセルの既定のフォルダのことだが、これ以外の場合は、ここで""でフォルダ名を囲んで指定するフォルダ名を入れる。
----
上記は各ブックを開く。
Sub test02()
Application.DisplayAlerts = False
Application.ScreenUpdating = False

Dim objfs
Dim objfolder
Dim wb
Dim buf As String
Set objfs = CreateObject("scripting.filesystemobject")
Set objfolder = objfs.getfolder(CurDir)
MsgBox CurDir
For Each objfile In objfolder.Files
If objfs.getextensionname(objfile) = "xls" Then
'MsgBox objfile.Name
'On Error Resume Next
target = "'" & CurDir & "\[" & objfile.Name & "]" & "Sheet1" & "'!R1C1"
MsgBox target
buf = ExecuteExcel4Macro(target)
MsgBox buf
End If
Next
Application.DisplayAlerts = False
Application.ScreenUpdating = False
End Sub
をやると、私の少数例では、スムーズに行く。
質問者の場合も、うまく行くか自信が無い。
上記のSheet1というシート名を「データ」に変えてやってみてください。質問の場合は各ブックで「データ」というシートだから、定数として、指定できるが、Sheets(1)などの名前が各ブックで違うと、お手上げと思う(ただ良い方法があるかも。開かないで第1シート名は、多分取れないだろうと思うが)。
このシート名のシートがその全てのブックに無い場合は、処理が止まるかと思う。
===
ExecuteExcel4Macro(target)
というのは、使用を勧められる物ではない。
基本的にエクセルは、開いてデータを読んで使うもの。
この点経験も少なく私も手探りだが、情報も少なく、初心者が「エクセルファイルを開かずに・・」なんて言えることではない。
この質問も丸投げで、回答者頼りで、やりたいことだけ勝手に言っているが、こんな課題は初心者には早すぎる課題だと思う。
参考
詳しくは、Googleで「ExecuteExcel4Macro」で照会して勉強のこと。
http://officetanaka.net/excel/vba/tips/tips28.htm

Dir関数に対しもうひとつの方法として、FSOを使う方法がある。
ーー
Sub test01()
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Dim objfs
Dim objfolder
Dim wb
Set objfs = CreateObject("scripting.filesystemobject")
Set objfolder = objfs.getfolder(CurDir)
MsgBox CurDir
For Each objfile In objfolder.Files
If objfs.getextensionname(objfile) = "xls" Then
MsgBox objfile.Name
Set wb = Workbooks.Open(objfile)
Windows(wb.Name).Visible = False
MsgBo...続きを読む

Qエクセル2000:同じ日付のレコードを削除したい

12/4
12/3
12/2
12/1
11/30
11/29
11/29
11/28
11/27
11/26
11/25

A列に上のような日付が入力され、B列以降には数値が入力されているとします。
上のように11/29のレコードが重複している場合、行番号が小さい上のほうのレコードを削除するようなマクロは組めますでしょうか。

急ぎませんので、ご存知の方がいらっしゃいましたらご教示をお願いいたします。

Aベストアンサー

VBAの方が素直にプログラムできますが、関数式でやって見ました。作業列を使いますが
(データ)Sheet3のA1:B11に(C列は下記式の結果を載せたもの)
A列       B列   C列
2004/12/4     a10
2004/12/3  b9
2004/12/2     c8
2004/12/1     d7
2004/11/30e6
2004/11/29f
2004/11/29g5
2004/11/28h4
2004/11/27I3
2004/11/26j2
2004/11/25k1
0
(関数式)
C11に(C1ではない。ダブリの下の方の行を取れと言うことからこうなる)に
=IF(COUNTIF($A$12:A12,A11)=0,MAX($C$12:C12)+1,"")
といれ、C10からC1に式を複写する。
上記のC列のようになる。同一日のダブリがあればその行を飛ばして連番を振る。
(関数式)
Sheet4のA1に
=INDEX(Sheet3!$A$1:$A$11,MATCH(11-ROW(),Sheet3!$C$1:$C$11,0),1)
をいれて、A10まで複写する。
B1にA1を複写し、最後の引数を2とする。
=INDEX(Sheet3!$A$1:$B$11,MATCH(11-ROW(),Sheet3!$C$1:$C$11,0),2)
B10まで複写する。
(結果)Sheet4
2004/12/4     a
2004/12/3     b
2004/12/2     c
2004/12/1     d
2004/11/30e
2004/11/29g
2004/11/28h
2004/11/27I
2004/11/26j
2004/11/25k
11月29日が1つになっている。

VBAの方が素直にプログラムできますが、関数式でやって見ました。作業列を使いますが
(データ)Sheet3のA1:B11に(C列は下記式の結果を載せたもの)
A列       B列   C列
2004/12/4     a10
2004/12/3  b9
2004/12/2     c8
2004/12/1     d7
2004/11/30e6
2004/11/29f
2004/11/29g5
2004/11/28h4
2004/11/27I3
2004/11/26j2
2004/11/25k1
0
(関数式)
C11に(C1ではない。ダブリの下の方の行を取れと言うことからこうなる)に
...続きを読む

Qエクセル2000:phonetic関数で漢字がひらがなに変わらない

お世話になります。
エクセルでアクセス等からインポートした「漢字氏名」文字はphentic関数を使っても、ひらがな(カタカナ)には、直らないようです。

「ひらがな」もしくは「カタナカ」強制変換できる方法をお教えください。お願いします。

Aベストアンサー

こんばんは。

あまり口を出すつもりはなかったのですが、

GetPhonetic
というのは、MS-IME のふり仮名候補の順番から引き出されるもので、GetPhoneticをそのまま使うと、MS-IMEの内部の順番の最初にあるものを出してきているに過ぎません。ただし、語の区切れの組み合わせによって、ふり仮名が変わる可能性があります。これは、MS-IMEを使用しているという条件が含まれています。

あまり、現実的なユーザー定義関数ではありませんが、#5さんの問題はこのようにすれば、解決できます。ただし、あまり、この種のユーザー定義関数は、必ず、貼り付けで、「値(定数)」に変えてしまったほうがよいかもしれません。

Function MyGetPhonetics(ByVal strText As String, Optional i As Integer = 0)
  Dim j As Integer
  Dim buf As String
  If Application.GetPhonetic(strText) = "" Or _
    Not strText Like "*[一-龝]*" Then
    MyGetPhonetics = strText
    Exit Function
  End If
  buf = Application.GetPhonetic(strText)
  Do Until i = j Or Application.GetPhonetic(strText) = ""
    buf = Application.GetPhonetic("")
    j = j + 1
  Loop
  MyGetPhonetics = buf
End Function

濱口 優

=MyGetPhonetics(A1)
とすれば、

ハマグチ ユウ

=MyGetPhonetics(A1,1)
と、第二引数に1を入れれば、

ハマグチ マサル

となります。

ご参考まで。

こんばんは。

あまり口を出すつもりはなかったのですが、

GetPhonetic
というのは、MS-IME のふり仮名候補の順番から引き出されるもので、GetPhoneticをそのまま使うと、MS-IMEの内部の順番の最初にあるものを出してきているに過ぎません。ただし、語の区切れの組み合わせによって、ふり仮名が変わる可能性があります。これは、MS-IMEを使用しているという条件が含まれています。

あまり、現実的なユーザー定義関数ではありませんが、#5さんの問題はこのようにすれば、解決できます。ただし、あまり、...続きを読む

QエクセルVBAで、とびとびのセルの順次選択方法?!

仮にA1:B10という範囲内で、空白のセルだけを一つずつ順番に選択しようと思い、以下のコードを書いてみました。
実行してみると、範囲内がすべて空白の場合にはA1→B1→A2→B2→・・・と、選択してくれます。
しかし、空白と空白以外のセルが混在していると、最初の空白セルから下に、範囲内の空白セル数分だけ、空白であると否とを問わず選択してしまいます。
( ̄□ ̄;)!!
myRngには空白セルだけを指定され、myRng.Cells.Countでもちゃんと空白セル数がカウントされます。
でも、myRng.Cells(i).Select では正しく選択されないのはなぜでしょうか?
Cells(i)を使用せず、ループを
For Each c In myRng
c.Select
Application.Wait Now + TimeValue("0:00:01")
Next c
で回せば選択できるのに・・・・・。

Sub test01()
Dim x As Long, i As Long, myRng As Range
With ActiveSheet
Set myRng = .Range("A1:B10").SpecialCells(xlCellTypeBlanks)
x = myRng.Cells.Count
For i = 1 To x
myRng.Cells(i).Select
Application.Wait Now + TimeValue("0:00:01")
Next i
End With
Set myRng = Nothing
End Sub

ご教示くださいませ。 (o。_。)oペコッ.

仮にA1:B10という範囲内で、空白のセルだけを一つずつ順番に選択しようと思い、以下のコードを書いてみました。
実行してみると、範囲内がすべて空白の場合にはA1→B1→A2→B2→・・・と、選択してくれます。
しかし、空白と空白以外のセルが混在していると、最初の空白セルから下に、範囲内の空白セル数分だけ、空白であると否とを問わず選択してしまいます。
( ̄□ ̄;)!!
myRngには空白セルだけを指定され、myRng.Cells.Countでもちゃんと空白セル数がカウントされます。
でも、myRng.Cells(i).Select で...続きを読む

Aベストアンサー

>結合セルに入力があってもSpecialCells(xlCellTypeBlanks)でひっかかる

いやー、値はある結合セル、までは考えていませなんだ。
まいった、まいった、というところでしょうか。(^^;;;


>If c.Address = c.MergeArea(1).Address And c.MergeArea(1) = "" Then と簡略化してもおなじですよね??

値なのでちゃんとValueプロパティを使ってちょと短くすると

If c.Address = c.MergeArea.Cells(1).Address And c.Value = "" Then
 
 
それから、かねがね当方もそのスキルの高さに敬服しているcj_moverさんの回答にもありますように
SpecialCells(xlCellTypeBlanks)が返す範囲は場合によっては
おい、おい、というようなものになることがありますので、
使うときは、先ず、Addressを表示確認した後に使った方がいいかも知れませんね。


何れにしろ、今回は当方にとっては再確認の旅になりました。
どこまでいってもエラーの出ないmyRng.Cells(i)の振る舞い、など。
とこまでいってもはちょと大袈裟????

ほんとに、ほんとに、ほんとに、これで最後。。。
続きは、cj_moverさんへバトンタッチ。。(^^;;;
ではでは。
 

>結合セルに入力があってもSpecialCells(xlCellTypeBlanks)でひっかかる

いやー、値はある結合セル、までは考えていませなんだ。
まいった、まいった、というところでしょうか。(^^;;;


>If c.Address = c.MergeArea(1).Address And c.MergeArea(1) = "" Then と簡略化してもおなじですよね??

値なのでちゃんとValueプロパティを使ってちょと短くすると

If c.Address = c.MergeArea.Cells(1).Address And c.Value = "" Then
 
 
それから、かねがね当方もそのスキルの高さに敬服しているc...続きを読む


このカテゴリの人気Q&Aランキング

おすすめ情報