• ベストアンサー

vbaでフォルダ属性がうまく取れません

vbaでフォルダ属性が隠しフォルダかどうかを調べるコードを書いています。 C:\ProgramData\ は隠しフォルダなのに、なぜか16が返って来ます。 試しにvbs(wsh)だと18が返って来ます。 環境は Win10 + Excel2013(32ビット) です。 vbaで返値18を求めるにはどうすれば良いのでしょうか。 Sub test() Dim mPath Dim fso, f mPath = "C:\ProgramData\" Set fso = CreateObject("Scripting.FileSystemObject") Set f = fso.GetFolder(mPath) MsgBox f.Attributes End Sub

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

  • ベストアンサー
  • pringlez
  • ベストアンサー率36% (598/1630)
回答No.9

興味があったのでいくつかの環境で調べてみました。 Win10 Excel2002 32bit 再現せず Win10 Excel2013 64bit 再現せず Win7 Excel2016 32bit 再現! という結果でした。 Excelの32ビット版の特定のバージョン(少なくとも2013-2016を含む)におけるバグなのではないかと思います。他の隠し属性付きフォルダでは発生しませんでしたので、フォルダ自体にも何か原因があるのかもしれません。しかし、VBSとExcel VBAで差が出ることはかなりおかしいので、VBA自体にもバグがあるのだと思います。 どうしてもVBAで値をとりたいのなら、少し面倒ですが、VBAからVBSを呼び出す形にすれば確実かと思います。

masnoske
質問者

お礼

とりあえず仕事で使うPC(Win7)では問題なく動作しました。 テスト的にVBAからVBSを呼び出してみたところ、問題なく動作しました。まぁ、当たり前と言えば当たり前ですが(笑)

その他の回答 (8)

回答No.8

UACによってC:\ProgramDataが仮想化されて、ユーザープロファイル内にあるリダイレクト先のフォルダの属性を取得している可能性があるのではないでしょうか?

  • kteds
  • ベストアンサー率42% (1876/4424)
回答No.7

不可解な状況であることは理解できます。 現時点で原因は解りません。 オブジェクトを使わずにGetattr()を使うとどうなりますか。 Sub test() Dim mPath mPath = "C:\ProgramData\" MsgBox Getattr(mPath) End Sub --- 上記でも16が返るのであれば 添付画像のようにコマンドプロンプトで attrib c:\programdata を実行して H が表示されていれば隠しフォルダです。( 18 が返る) H が表示されていなければ隠しフォルダではありません。( 16 が返る)

masnoske
質問者

お礼

VBAにGetAttr関数があるんですね。勉強になりました。肝腎の結果ですが、残念ながら16が返ってきました。 コマンドプロンプトの方は、HとI が返って来ました。どうもVBAの動作が怪しいように思います。

  • bunjii
  • ベストアンサー率43% (3589/8248)
回答No.6

>エクスプローラーでプロパティを確認しましたが、隠しフォルダにチェックが入っています。 VBAで隠しフォルダーの属性を付与してみてはいかがですか? また、他のPCで同じVBAコードを実行してみるのも比較として参考になるでしょう。 何れにしてもOS(Windows 10)のファイル管理機能に不具合が生じているかも知れません。 VBAのコードが原因ではないと思います。

masnoske
質問者

お礼

エクスプローラーから隠し属性をON/OFFして実行しましたが結果は変わらずでした。 試しに VBAから Attributes = 16 をセットするとVBAもVBSも返値は16で、エクスプローラーの属性も隠し属性OFFです。 次に VBAから Attributes = 18 をセットするとVBAの返値は16、VBSは18です。エクスプローラーの属性は隠し属性ONです。

noname#232800
noname#232800
回答No.5

確かに、私は隠し属性はOFFでした。 試しにLinuxでは、どうなるか・・・再起動してドライブが無いという事に気づきました。 カレントなら、異なるOSでも取れるし、互換性ができます。ProgramDataを取ってはいけないのですね。

  • kteds
  • ベストアンサー率42% (1876/4424)
回答No.4

フォルダ属性=16 ,隠し属性=2 ですので16+2=18でなければいけません。 16ということはフォルダ属性しか取得していないことになります。 mPath = "C:\ProgramData" ではどうなりますか

masnoske
質問者

お礼

mPath = "C:\ProgramData" としても同じです。 アップデートの更新に何度か失敗して更新できていないパッチがあったようなので、最新に更新してみましたがダメです。

  • bunjii
  • ベストアンサー率43% (3589/8248)
回答No.3

>Excelが32ビットか64ビットの違いでしょうか? 違うと思います。 エクスプローラーで目的のフォルダーを確認してみると良いでしょう。 隠し属性が解除されているかも知れません。 通常フォルダーの返り値が16で隠し属性の2を加算した18になるはずです。 VBAはプログラム言語なのでOSや利用するアプリケーションによって異なる結果を返すはずはありません。

masnoske
質問者

お礼

隠し属性は解除されていません。 エクスプローラーで隠しファイルの表示をONにしてもOFFにしても結果は同じです。ちなみに隠しファイルの表示をONにすると、C:\ProgramData\ は 半透明に表示されますので、隠し属性は解除されていないと思います。

masnoske
質問者

補足

試しに別の隠しフォルダ "C:\Program Files\WindowsApps\" で確認したところ、VBAでもVBSでも18が返って来ました。 どうやら "C:\ProgramData\" が変なようです。 エクスプローラーでプロパティを確認しましたが、隠しフォルダにチェックが入っています。

  • bunjii
  • ベストアンサー率43% (3589/8248)
回答No.2

私の環境(Win10、Excel 2013 64bit)では提示のコードでMsgBoxへ18と表示されます。

masnoske
質問者

お礼

Excelが32ビットか64ビットの違いでしょうか? 再起動して確認しましたが、やっぱりExcelでは16が返って来ます。

noname#232800
noname#232800
回答No.1

LibreOffice Calc で「18」が返ってきました。 Windows7 SP2 + LibreOffice5.4

masnoske
質問者

お礼

環境が違うと問題ないのですね。

関連するQ&A

  • VBScriptで、任意のフォルダコレクションを取得するには?

    VBScriptについて質問します(マイナーですみません) 任意のフォルダコレクションを取得して、 そのフォルダ名を1つ1つ得たいんですが、 うまくいきません。 FileSystemObjectを作成して、 任意のフォルダ(MyFolder)を取得することはできました。 Set fso=CreateObject("Scripting.FileSystemObject") Set f=fso.GetFolder("C:/....../デスクトップ/MyFolder") いま、MyFolder の下に、複数のサブフォルダがあるとき、 サブフォルダのコレクションを取得して、 サブフォルダ名を1つ1つ得るには、 どうしたらいいのでしょうか? よろしくおねがいします。

  • フォルダをリネームしたい

    いつもお世話になっております。 フォルダの名前を変更しようとしていますが、うまくいきません。 ASP(VBS)にて行ってます。 以下のように書いてみましたが、フォルダ名が変更されません。 以下ソース。 「12345」というフォルダ名を「67890」に変更したいのです。 <% Dim fso, f, s Set fso = CreateObject("Scripting.FileSystemObject") Set f = fso.GetFolde("./uploads/12345") f.Name = "67890" %> どなたかご存知の方がいらしゃいましたら、ご教授お願いします。

  • VBSのFor文

    VBSのドキュメントをダウンロードし、その中にFor文のサンプルがあったんですが、この構文の"f1"はどういった役割をしているのでしょうか?教えてください。 Dim fso, f, fc, f1,s Set fso = CreateObject("Scripting.FileSystemObject") Set f = fso.GetFolder("c:\work") Set fc = f.files For Each f1 in fc s = f1.name Next

  • VBA SFO C:\Windows

    Cドライブには、 IntelもWindowsのどちらのフォルダも存在するのに Sub Sample() Dim myFSO As Object Debug.Print CreateObject("scripting.filesystemobject").GetFolder("C:\Intel").Size Debug.Print CreateObject("scripting.filesystemobject").GetFolder("C:\Windows").Size Set myFSO = Nothing End Sub をVBAで実行すると \Windows の方だけエラーになります。 エラー内容は 実行時エラー 70 書き込みできません。 です。 何故でしょうか?

  • VBA:2つのCSVファイルを開きたいです。

    エクセル2010のVBAにてCSVファイルを開き結合させるプログラムを組もうとしているのですが、2つ目のCSVファイルを開こうとすると、何故かエラーが出てしまいます。 -------------------------------------------------------------------------------- 1つ目 Sub mobile_FileSearch(Path As String) 'test.csvのデータを検索して開く Dim FSO As Object, Folder As Variant, File As Variant Set FSO = CreateObject("Scripting.FileSystemObject") For Each Folder In FSO.GetFolder(Path).SubFolders Call mobile_FileSearch(Folder.Path) Next Folder For Each File In FSO.GetFolder(Path).Files If File.Name = "test.csv" Then Workbooks.Open ("test.csv") End If Next File End Sub ---------------------------------------------------------------------------- 2つ目 Sub local_FileSearch(Path As String) 'bbb.csvのデータを検索して開く Dim FSO As Object, Folder As Variant, File As Variant Set FSO = CreateObject("Scripting.FileSystemObject") For Each Folder In FSO.GetFolder(Path).SubFolders Call local_FileSearch(Folder.Path) Next Folder For Each File In FSO.GetFolder(Path).Files If File.Name = "bbb.csv" Then Workbooks.Open ("bbb.csv")'←ここでエラー End If Next File End Sub ------------------------------------------------------------------------ まったく同じプログラムで、csvファイル名だけ変えただけで実行時エラー1004が出てしまいます。 一体全体何が問題なのでしょうか?

  • FSOを使いサブフォルダのファイル操作

    同じ階層のサブフォルダにxlsm入るが入っており、VBAによりモジュールを解放しようと試みています。 まずは、FSOを使ってサブフォルダにアクセスしようとしましたが、下から6行目でエラー(424 オブジェクトが必要です)が出てしまい、解決できませんので、ご教示いただけないでしょうか? よろしくお願いします Sub DeleteMain() With Application.FileDialog(msoFileDialogFolderPicker) If Not .Show Then Exit Sub Call DeleteSub(folderPath:=.SelectedItems(1)) End With End Sub Sub DeleteSub(folderPath As String, Optional mycount As Long = 0) Dim fso As Object, myFolders As Object, myfile As Object Set fso = CreateObject("Scripting.FileSystemObject") Set myFolders = fso.GetFolder(folderPath).SubFolders For Each myfile In fso.GetFolder(folderPath).Files mycount = mycount + 1 ' Cells(mycount, 1) = myfile.Path Debug.Print myfile.Path Next For Each myFolders In fso.GetFolder(folder.Path).SubFolders Call DeleteSub(myFolder.Path, mycount) Next Set fso = Nothing Set myFolders = Nothing End Sub

  • VBAでアクティブなファイルを参照して、ファイル一覧作成(サブフォルダ含む)

    VBAでアクティブなファイルのフォルダ(サブフォルダを含む)のファイル一覧を 作成したいと思っています。 以下のサイトを参考にして、パス、ファイル名を落とすまではできました。 http://okwave.jp/qa3544575.html === Sub test() Application.ScreenUpdating = False Sheet1.Cells.Clear Sheet1.Cells(1, 1) = "パス" Sheet1.Cells(1, 2) = "ファイル名" files "d:\", 2 Application.ScreenUpdating = True End Sub Sub files(path As String, ByRef row As Long) DoEvents Dim fso As Object Set fso = CreateObject("Scripting.FileSystemObject") Dim f As Object For Each f In fso.GetFolder(path).files Sheet1.Cells(row, 1) = path Sheet1.Cells(row, 2) = f.Name row = row + 1 Next For Each f In fso.GetFolder(path).SubFolders files f.path, row Next Set fso = Nothing End Sub === >files "d:\" の箇所を修正して、アクティブなブックを参照しようとしてみたのですが、 なかなか上手くいきません。 また、できれば *.xls などファイルの種類を指定したいのです。 filesearchを使用して組んだ時は 「AAA = ActiveWorkbook.path」「Filetype ~ 」 などでそれらの指定ができたのですが、上記に応用する事ができません。 どなたかご教示頂けますよう、よろしくお願いいたしますm(_ _)m

  • EXCEL VBAでフォルダ容量の測定

    お世話になります. EXCELでフォルダの容量を自動で測量するツールを作成中です. 大まかな概要としては,1枚目のシートのセルにあらかじめ測定対象となるフォルダのパスを記述しておき, そのパスをもとに2枚目のシートに測定した容量を出力したいと考えています. 作成中のソースから抜粋させて頂きますが,以下の部分が上手くいきません. <<作成中のソース>> Sub FolderSize_Count() Dim FSO As Variant Set FSO = CreateObject("Scripting.FileSystemObject") Dim Path As String With Sheets("Sheet2") Path = Application.Worksheets("sheet1").Range("A1").Value .Cells(1, 1) = FSO.GetFolder("Path").Size End With End Sub <<不明点>> FSO.GetFolder("Path").Size の"Path"の部分には対象フォルダのパスを記述する必要があるが, 別シートから取得した値を" "に反映させる記述が分かりません. ちなみに Application.Worksheets("sheet1").Range("A1").Valueにて,対象フォルダのパスを取得出来ていることと, FSO.GetFolder("C:\test").Sizeにて,Cドライブ直下のtestフォルダの容量を取得できることは確認済みです. お手数お掛けいたしますが,有識者の方,ご教授頂ければ幸いです. 以上,よろしくお願いいたします.

  • エクセル2010のVBAを使ってバックアップ

    エクセル2010のVBAを使ってバックアップを取れる仕組を作っています。 Sub backup() Dim FSO As Object Set FSO = CreateObject("Scripting.FileSystemObject") FSO.CopyFile "C:\data\*.xls", "C:\back\" Set FSO = Nothing End Sub 実際にバックアップを取りたい元データはマイドキュメントにあります。 また、複数のパソコンで実行したいのですが、 C:\Documents and Settings\ログインユーザー名\MyDocuments\ このログインユーザー名がバラバラです。 データ元のパスはどのように取得すれば良いでしょうか? 教えて下さい。

  • 再度:VBSで指定したフォルダー内のファイルを書き出さないようにする

    先ほども似たような質問をしました。 あるフォルダの中にあるファイル名の一覧をファイル"f.name.txt"を書き出したいのですが"新しいフォルダ"のなかにあるファイルは書き出さないようにしたいです。下記のVBSは"新しいフォルダ"のなかに更にフォルダが階層的に存在するときには"新しいフォルダ"の中のファイルも全て書き出してしまいます。 "新しいフォルダ"の中にフォルダがない場合は正しく動きます。 "新しいフォルダ"の中にフォルダが階層的にあっても"新しいフォルダ" の中にあるファイル名を書き出さないようにするにはどうしたらよいのでしょう? ************************************************************** Set FSO = CreateObject("Scripting.FileSystemObject") Set fl = WScript.CreateObject("Scripting.FileSystemObject") Set abc = fl.CreateTextFile("f.name.txt") ShowSubfolders FSO.GetFolder(".") Sub ShowSubFolders(Folder) If Folder.Name <> "新しいフォルダ" Then For Each File in Folder.Files 'Folder内のファイルを列挙する Fname = File.name abc.Write Folder & "\" & Fname & vbCrLf Next End If For Each Subfolder in Folder.SubFolders 'Folder内のフォルダを列挙する ShowSubFolders Subfolder '再帰呼び出し Next End Sub abc.Close

専門家に質問してみよう