WindowsXP、VB6.0でデレクトリをTreeViewに表示するプログラムです。
フォームにTreeViewコントロールとコマンドボタンを貼り付け、
下記のプログラムを実行します。
curFolder.Name に "System Volume Information" がでると
エラーになり、それを回避するために "On Error Resume Next"をいれて
EXEファイルを作り、実行するとフォームが消えてしまいます。
どなたか教えて下さい。

Private Sub Command1_Click()
' Microsoft Scripting Runtime を参照設定する。
Dim item1 As Node, FsoObj As New scripting.FileSystemObject
Set item1 = TreeView1.Nodes.Add(, , , "c:")
Call SearchFolder(FsoObj.GetFolder("c:\"), item1)
End Sub

Private Sub SearchFolder(NextFolder As scripting.Folder,
              itemX As Node)
On Error Resume Next
Dim TreeItem As Node, curFolder As scripting.Folder
For Each curFolder In NextFolder.SubFolders
' Debug.Print curFolder.Path
Set TreeItem = TreeView1.Nodes.Add(itemX.Index,
               tvwChild, , curFolder.Name)
Call SearchFolder(curFolder, TreeItem)
Next
End Sub

A 回答 (5件)

このフォルダにはインデックスサービスを利用してファイル検索を高速にするための情報が入っているようです。


しかし、この中身を勝手に参照されると困るようで、アクセス制御によってどんなファイルが入っているかはもちろん、このフォルダの作成日時なども見られないようになっています。
管理者は無理矢理このフォルダの内容を見ることができますが、やめたほうがいいでしょう。
よって、このフォルダの中身を参照しようとすると、VBの場合実行時エラーが発生します。

これは、おそらくFileSystemObjectを使っているのが原因で、このオブジェクトはフォルダ名を参照するだけでもそのフォルダの情報を取得しようとしている可能性があります。
API関数なら "参照できませんでした、はい残念" で済むのですが、VBコンポーネントの場合、外側でOn Error Resume Nextを指定しても中まで届かないことがあるみたいです。

API関数を使う方法を知っていますか?

WIN32_FIND_DATA
FindFirstFile
FindNextFile
FindClose

これらのキーワードで検索してみてください。
    • good
    • 0
この回答へのお礼

回答有難う御座います。
TreeViewにすべてのフォルダを表示するには、フォルダの再帰検索を
しなければなりませんが、Dir関数を使って無理やり再帰検索すると
かなり面倒なプログラムになります。
このMicrosoft Scripting Runtimeを参照設定して、FileSystemObjectを
使うと嘘のように簡単になるので、「これはいい!」と
思ったのですが.....。 駄目なようですね。
そのAPI関数を使うか、あるいはVBでフォルダの再帰検索をすると
かなり時間がかかるので、VC++でフォルダ再帰検索のActiveXを作って
そのOCXを参照設定するか、これから検討してみます。
大変参考になりました。有難うございました。

お礼日時:2002/02/20 20:01

VCでOCXを作る力があるくらいなら、VBからAPIでファイルリストを作ることも簡単でしょう。



>かなり時間がかかるので
じつは、FileSystemObjectは、あまり効率のいい構造はしていないみたいです。
フォルダやファイル1つ1つが固有のオブジェクトになっているため、検索のたびにそれぞれがインスタンスを作るので、余計なメモリも消費されているようです。

FindFirstFileは作成時間や属性なども同時に取得してくれるので、エクスプローラの様なアプリケーションを作るために必要な情報は、一通りそろっています。
それでも、FileSystemObjectの10倍くらい速いみたいです(根拠なし)。

楽してインターフェースから作り始めるのもいいですが、内部からごりごり作っていくのもおもしろいですよ。
がんばってください。

この回答への補足

有難うございます。
>VCでOCXを作る.......。
などと表面だけ見ると、いかにも実力がありそうにみえますが実際は
参考書とのにらみ合いになるでしょう。

補足日時:2002/02/20 20:31
    • good
    • 0

if(curFolder.Path = "System Volume Information")then


else
end if

この回答への補足

>if(curFolder.Path = "System Volume Information")then
>else
>end if

回答有難うございます。
上記のサンプルを実行してみましたが、"For Each ....." の所で
"書き込み出来ません"のエラーが出て駄目でした。

補足日時:2002/02/19 18:56
    • good
    • 0

>EXEファイルを実行した時に、多分エラーになるファイルをアクセスした時に


>消えてしまうのではないかと思っています。

それなら、MsgBox curFolder.Pathを入れることにより、エラーになるファイル
を含むフォルダを特定できるのでは?

この回答への補足

>それなら、MsgBox curFolder.Pathを入れることにより、
>エラーになるファイルを含むフォルダを特定できるのでは?

再度の回答、有難う御座います。

最初の質問に書きましたが "System Volume Information" をアクセスした
時にエラーになるようです。何かシステムに関係あるファイルのようで
Cドライブにも、Dドライブにもあります。何故このフォルダ(?)を
アクセスした時にエラーになるのか、あるいはこのフォルダ(?)を
アクセスしないようにすれば、実行画面が消えないのでは....と
思いますがそれが分かりません。

補足日時:2002/02/19 16:35
    • good
    • 0

>' Debug.Print curFolder.Path



MsgBox curFolder.Path にしてみては?

この回答への補足

>MsgBox curFolder.Path にしてみては?

早速の回答、有難うございます。
' Debug.Print curFolder.Path はどんなファイルをアクセスした時に
エラーになるのかを確認するためにいれてあります。実行ファイル作成時は
コメントにしています。
VBのデバッグ環境では正常に動作しますが、EXEファイルを
実行した時に、多分エラーになるファイルをアクセスした時に
消えてしまうのではないかと思っています。このような事は初めてなので
とまどっています。

補足日時:2002/02/19 14:11
    • good
    • 0

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

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

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

QExcelでマクロ実行中に画面を固定する方法

Excelでマクロ(VBA)を実行しているとお考えください。
内容は他のシートのデータを別のシートにコピー&ペーストするとお考えください。
すると、画面がめまぐるしく動きます。
これをとめる方法をご存知の方教えていただければうれしいです。
(以前、やったことがあるんですが、忘れてしまいました)
(また、検索で調べようとしたのですが、どのようなキーワードで検索すればいいのかわかりませんでした(私のキーワードでは見つかりませんでした))
よろしくお願いいたします。

Aベストアンサー

はじめまして.

以下のコマンドでできると思いますよ。

マクロの最初に
Application.ScreenUpdating = False '画面更新抑止
を入れて、

マクロの最後に
Application.ScreenUpdating = True '画面を更新
を入れる。

こんなのでどうでしょう!?
では。

QDoEvents関数って何?

こんにちは。

VBAやプログラミングに詳しい皆様に
教えていただきたい質問があります。

cells(1,1)からcells(5000,1)までの値を消去するときに
処理の進行状況を表示するためにuserform上にプログレスバーを表示したいと思います。

そこで下記のようなコードを入力しました。

userform1.show
for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
next i
unload userform1

しかしこれだとuserformの背景が真っ白になってしまい
ラベルの文字も消えてしまいます。
そこで「EXCEL VBA パーフェクトマスター」という本を見たら

for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
DoEvents
next i
unload userform1
と入力すれば解決することがわかりました。

しかし「DoEvents」についてあまり詳しく書いていなかったのでDoEvents関数をヘルプで見ると、
「発生したイベントがオペレーティング システムによって処理されるように、プログラムで占有していた制御をオペレーティング システムに渡すフロー制御関数です。」

と書いてあるのですが正直、書いてあることがよくわかりません。

どなたかDoEvents関数について、
もう少しわかりやすく教えていただけませんか。
それから、最初に書いたコードで実行すると
ユーザーフォームの背景が真っ白になってしまう原因も
教えていただけませんか?

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

こんにちは。

VBAやプログラミングに詳しい皆様に
教えていただきたい質問があります。

cells(1,1)からcells(5000,1)までの値を消去するときに
処理の進行状況を表示するためにuserform上にプログレスバーを表示したいと思います。

そこで下記のようなコードを入力しました。

userform1.show
for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
next i
unload userform1

しかしこれだとuserformの背景が真っ白になってしまい
ラベルの文字も消えてしまいます。
そ...続きを読む

Aベストアンサー

簡単に言うと、
OS に制御を渡すってことです。(ヘルプそのまんま)
時間が掛かるループ処理などの場合、ループが終わるまで制御は独占されてしまいます。
ですのでループ中は OS や Excel そのものにも再描画をさせる暇さえ与えません。
途中に DoEvents を入れると制御が OS に渡るので、OS は溜まっていた処理をそこで行うことができます。
結果、フォームの再描画などが行われることになります。

注意点ですが、
Private Sub CommandButton1_Click()
  Dim i As Long

  For i = 1 To 50000
    DoEvents
    Cells(i,1) = ""
  Next i
End Sub

Private Sub CommandButton2_Click()
  MsgBox "hoge"
End Sub

っていうフォームのコードがあった場合、
DoEvents を入れることによって、ループ中にユーザーがCommandButton2 を押すことによって CommandButton2 のクリック イベントも動いちゃいます。
CommandButton1 のクリック イベントではループの前に
CommandButton1.Enabled = False
CommandButton2.Enabled = False
を書いてフォーム上の CommandButton を無効にしておき、ループが終わったら
CommandButton1.Enabled = True
CommandButton2.Enabled = True
と書いて CommandButton を有効に戻してください。

これを工夫すれば、CommandButton2 で CommandButton1 のループを途中キャンセルする処理もすることができます。

Private Canceled As Boolean

Private Sub CommandButton1_Click()

  CommandButton2.Enabled = False

  Dim i As Long
  For i = 1 To 50000
    DoEvents

    If Canceled = True Then
      MsgBox "キャンセルしました"
      Exit Sub
    End If

    Cells(i, 1).Value = ""
  Next i
End Sub

Private CommandButton2_Click()
  Canceled = True
End Sub



コードの行頭にあるスペースは見易さのために全角スペースで作成していますので、これをこのままコピペするとエラーになるかもしれません。
コピペするなら行頭の全角スペースを半角スペースに直してください。

簡単に言うと、
OS に制御を渡すってことです。(ヘルプそのまんま)
時間が掛かるループ処理などの場合、ループが終わるまで制御は独占されてしまいます。
ですのでループ中は OS や Excel そのものにも再描画をさせる暇さえ与えません。
途中に DoEvents を入れると制御が OS に渡るので、OS は溜まっていた処理をそこで行うことができます。
結果、フォームの再描画などが行われることになります。

注意点ですが、
Private Sub CommandButton1_Click()
  Dim i As Long

  For i = 1 To 50000
...続きを読む

QVBAでエクセルシートを更新(リフレッシュ)する方法を教えて下さい。

マクロを含むエクセル(EXCEL2000)をHTMLのページからハイパーリンクで呼び出しています。そのエクセルでボタン操作に従い罫線やセルの着色を行っています。しかし、着色結果が更新されません。スクロールバー等で画面を移動すると正しく着色されています。このエクセルを通常に起動した場合は、問題なく動作するのですが、シート全体を更新する方法を教えて下さい。
各関数では、以下のスクリーンアップデータの処理を入れています。
Application.ScreenUpdating = False
    (処理)
Application.ScreenUpdating = False

Aベストアンサー

たぶん、EXCEL独特の問題だと思うのですが、HTML の場合、すでに色の部分を表面上で使用しているので、それでメモリが占有させているのではないかと私は思っています。

他にも、

 ActiveWorkbook.HTMLProject.RefreshDocument True

というのがありますね。
ホスト アプリケーション内のブックに含まれる HTML プロジェクトを更新する、というのがありますね。

Qエクセル マクロで指定フォルダを開く

エクセルにて
指定フォルダを開く、マクロがあれば教えて頂けないでしょうか。
よろしくお願いいたします。

Aベストアンサー

こんにちは。

こういうものですか?
開くフォルダを変えたいときは targ に与えるパスを変更します。

Sub OpenFolders()
Dim targ As String
targ = "C:\"
Shell "C:\Windows\Explorer.exe " & targ, vbNormalFocus
End Sub

QEXCEL VBA で現在開いているブックのファイル名を取得する方法

EXCEL2003 VBAで業務を簡素化するために、現在開いているブックのファイル名を取得する方法が分かりません。
作業手順をマクロを使って処理していますが、オリジナルのワークブックをファイル名を変えて保存し、以後、このワークブックを読み込んで使用しています。
このときのVBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり、以後の業務に使用できません。
常にファイル名を取得出来るVBAをどなたか、教えて下さい。

Aベストアンサー

>現在開いているブックのファイル名
 ちょっと曖昧な表現かなぁという気もいたしますが、VBAが書いてあるブックのブック名は
ThisWorkbook.Name
で、現在 "アクティブにして" 操作対象になっているブックの名前は
ActiveWorkbook.Name
ですね。

 しかし、
>VBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり
というような文脈からすると、
ThisWorkbook.Name
の方ですかね。

QMSCOMCTL.OCXのアップデートの方法

Excel VBAを使っていて
ListviewなどのMSCOMCTL.OCXに依存した
コントロールを使っている場合
MSCOMCTL.OCXに上位互換性がないため、
VBAを含むxlsmファイルを作成したPCとは異なるPCで
そのプログラムを使用するためには
使うPCごとにMSCOMCTL.OCXをアップデートする必要があります。

http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1198163781

詳細はこのページに書かれてあります。

疑問は、いま、自分が使っているMSCOMCTL.OCXのバージョンが2012年のものなのですが
Windows10にアップグレードするなどした場合に
MSCOMCTL.OCXをアップグレードする必要がありますが
VBAは正常に動作するのでしょうか?

MSCOMCTL.OCXには下位互換性があるのでしょうか?

もし動作しないとして、
一つずつListviewを削除して新規作成するという作業を行う必要があるのでしょうか?
自動更新できる方法があれば教えてください。

Excel VBAを使っていて
ListviewなどのMSCOMCTL.OCXに依存した
コントロールを使っている場合
MSCOMCTL.OCXに上位互換性がないため、
VBAを含むxlsmファイルを作成したPCとは異なるPCで
そのプログラムを使用するためには
使うPCごとにMSCOMCTL.OCXをアップデートする必要があります。

http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1198163781

詳細はこのページに書かれてあります。

疑問は、いま、自分が使っているMSCOMCTL.OCXのバージョンが2012年のものなのですが
Windows10に...続きを読む

Aベストアンサー

>Win10 PCで作成したVBAをWin7 PCにコピーして使用するためには、
>「~7.0(SP6)(仮称)」にチェックを入れる必要があるはずです。
その場合にはWin7PCではMicrosoft ListView Control 6.0(SP4)にチェックを入れなおせば
まず問題ないはずです。
ちなみに当方のWin7 Office2010 のMicrosoft ListView Controlの実体ファイルの
製品バージョンは6.01.9839
Win10 Office2016(プレビュー版)のmscomctl.ocxのバージョンも同一でした。
単純なテストですが、2016 → 2010 では問題なかったです
VBAはよく言えば枯れた状態ですので大々的なアップデートは無いでしょう。
あったとしたらMicrosoft ActiveX Data Object x.x Libraryと同様
Microsoft ListView Control 6.0・・・
Microsoft ListView Control 7.0・・・
のように複数バージョンが並行して登録されるとおもいます。

>オフィスを常にアップデートして最新の状態にしておく必要があるということでしょうか?
大多数の人は更新プログラムを自動的にインストールする設定にしたままだと思います。
最新にというかリビジョンを合わせた方がつまらないトラブルにならないと思います。
ただ、近年のアップデートは地雷が多すぎて何とも言えなくなりました。。。

>Win10 PCで作成したVBAをWin7 PCにコピーして使用するためには、
>「~7.0(SP6)(仮称)」にチェックを入れる必要があるはずです。
その場合にはWin7PCではMicrosoft ListView Control 6.0(SP4)にチェックを入れなおせば
まず問題ないはずです。
ちなみに当方のWin7 Office2010 のMicrosoft ListView Controlの実体ファイルの
製品バージョンは6.01.9839
Win10 Office2016(プレビュー版)のmscomctl.ocxのバージョンも同一でした。
単純なテストですが、2016 → 2010 では問題なかったです
VBAはよく言えば枯れた状...続きを読む

Q[VBA]標準機能のみでパス付zipファイルの解凍

いつもこちらの識者の皆様にはお世話になっております。
VBAのことで質問させてください。

環境はwindows7 Pro
Excel2010(14.0.7128.5000) 32bit
です。

掲題のとおり、パスワード付のzipファイルを解凍しいたいのですが、調べてもやり方が分からず困っています。

■やりたいこと
外部アプリケーションを使わずにWindows7の標準機能のみで"C:\aaa\bbb.zip"をパスワード"111"で解凍する

会社で使っているのですが、アプリケーションのインストールが禁止されており、
毎日複数のパスワード付zipファイルを手動で解凍して処理をしています。
効率を考えVBAで処理したいのですが、どなたか上記内容の場合どのようなコードが適しているか
教えていただけませんでしょうか。
よろしくお願いいたします。

Aベストアンサー

こんばんは。
>>ついでに、その掲示板の質問者さんは、・・・
>実はこの質問も僕なんです。
失礼しました。気が付きませんでした。(^^;

>zipfldr.dllで圧縮・解凍処理をしてるんですね。
これが、私には使いこなせなかったのです。それで、試行錯誤の上、結局、Shell.Application で任せてしまいました。(おそらく、古い環境では動きません)

>ひとまず単一のパス付きzipファイルを解凍するコードをご教示いただければありがたいです。
実に、へんてこなコードですが、試してみてください。こちらの環境ではうまくいきましたが、他人の環境では、失敗する可能性が結構あります。Sendkeyは、Win32 API関数の方が確実ですが、仰々しくなってしまいます。


'//
Sub OneZipExtract()
 Dim fn As Variant
 Dim DestFolder As Variant
 Dim objZip As Variant
 '出来る限り、VBEditor は閉じていたほうがSendkeyの誤動作から免れます。
 Const PSWD As String = "000" 'パスワード
 DestFolder = "C:\aaa\" '展開フォルダ 末尾は、¥(セパレータ)を置くようにしてください。
 
' fn = Application.GetOpenFilename("ZIPファイル*.zip(*.zip),*.zip")
' If VarType(fn) = vbBoolean Then Exit Sub
 fn ="C:\aaa\bbb.zip"  'キメウチ・ファイル名
 ' DestFolder = Mid(fn, 1, InStrRev(fn, "\")) '展開ファルダが、ZIPファイルのある場所の場合
 Set objShell = CreateObject("Shell.Application")
 Set objZip = objShell.Namespace(fn).Items
 Application.SendKeys PSWD & "{Enter}"
 objShell.Namespace(DestFolder).CopyHere (objZip) '*
 Set objShell = Nothing
End Sub
'//

*確実にZIPファイルが展開できたかは、このようにすると良いです。
 ret = objShell.Namespace(DestFolder).CopyHere(objZip)
 If ret > 0 Then
   MsgBox "失敗しました。", 48
 End If

こんばんは。
>>ついでに、その掲示板の質問者さんは、・・・
>実はこの質問も僕なんです。
失礼しました。気が付きませんでした。(^^;

>zipfldr.dllで圧縮・解凍処理をしてるんですね。
これが、私には使いこなせなかったのです。それで、試行錯誤の上、結局、Shell.Application で任せてしまいました。(おそらく、古い環境では動きません)

>ひとまず単一のパス付きzipファイルを解凍するコードをご教示いただければありがたいです。
実に、へんてこなコードですが、試してみてください。こちらの環境ではうま...続きを読む


人気Q&Aランキング