A 回答 (6件)
- 最新から表示
- 回答順に表示
No.6
- 回答日時:
動作確認用に入れた下記処理が残っていました。
削除しといてください。List1.AddItem CStr(RoundUp(MergeDWORD(lngFileSizeHigh, lngFileSizeLow), lngClusterSize)) & " " & strFolderName & "\" & fil.Name
No.5
- 回答日時:
ちょっとサンプルを作ってみました。
実際に使うには、いろんな環境で確認してから使ってください。使用方法は、getFolderSize("c:\temp")のようにパス名を指定して関数を呼んでください。結果は、2GB以上でもOKなようにCurrency型で返ります。
尚、WindowsのAPIの定義は、APIビューワからコピーしてください。
' 指定したフォルダのディスク上のサイズを求める
Function getFolderSize(strFolderName As String) As Currency
Dim udtVersionInfo As OSVERSIONINFO ' OSのバージョン取得用
Dim fso As FileSystemObject ' FileSystemObject のハンドル
Dim fldr As Folder ' フォルダオブジェクトのハンドル
Dim sfldr As Folder ' サブフォルダのオブジェクトのハンドル
Dim fil As File ' ファイルオブジェクトのハンドル
Dim curSum As Currency ' ファイルサイズの合計
Dim lngFileSizeHigh As Long ' ファイルサイズの上位 DWORD
Dim lngFileSizeLow As Long ' ファイルサイズの下位 DWORD
Dim lngReturnValue As Long ' 戻り値
Dim lngSectorsPerCluster As Long ' セクタ数/クラスタ
Dim lngBytesPerSector As Long ' バイト数/セクタ
Dim lngNumberOfFreeClusters As Long ' 空きクラスタ数
Dim lngTotalNumberOfClusters As Long ' 全クラスタ数
Dim lngClusterSize As Long ' クラスタサイズ
' 合計をクリア
curSum = 0
' OSのプラットフォームを調べる
udtVersionInfo.dwOSVersionInfoSize = Len(udtVersionInfo)
lngReturnValue = GetVersionEx(udtVersionInfo)
' ドライブのクラスタサイズを調べる
lngReturnValue = GetDiskFreeSpace(Left(strFolderName, 3), lngSectorsPerCluster, lngBytesPerSector, lngNumberOfFreeClusters, lngTotalNumberOfClusters)
lngClusterSize = lngSectorsPerCluster * lngBytesPerSector
' FileSystemObject オブジェクトの作成
Set fso = New FileSystemObject
' フォルダオブジェクトのハンドルを取得
Set fldr = fso.GetFolder(strFolderName)
' サブフォルダを列挙し、再帰的に呼び出す
For Each sfldr In fldr.SubFolders
curSum = curSum + getFolderSize(sfldr.Path)
Next sfldr
' ファイルを列挙し、ディスク上のファイルサイズを求める
For Each fil In fldr.Files
If udtVersionInfo.dwPlatformId = "1" Then ' 95系OS
curSum = curSum + RoundUp(fil.Size, lngClusterSize)
Else
If Right(strFolderName, 1) = "\" Then
lngFileSizeLow = GetCompressedFileSize(strFolderName & fil.Name, lngFileSizeHigh)
Else
lngFileSizeLow = GetCompressedFileSize(strFolderName & "\" & fil.Name, lngFileSizeHigh)
End If
curSum = curSum + RoundUp(MergeDWORD(lngFileSizeHigh, lngFileSizeLow), lngClusterSize)
List1.AddItem CStr(RoundUp(MergeDWORD(lngFileSizeHigh, lngFileSizeLow), lngClusterSize)) & " " & strFolderName & "\" & fil.Name
End If
Next fil
' オブジェクトの解放
Set fil = Nothing
Set sfldr = Nothing
Set fldr = Nothing
Set fso = Nothing
' 合計を戻り値にセット
getFolderSize = curSum
End Function
' 2つのDWORDに分割された値をCurrency型に変換
Function MergeDWORD(lngFileSizeHigh As Long, lngFileSizeLow As Long) As Currency
If (lngFileSizeLow And &H80000000) = &H80000000 Then
MergeDWORD = CCur(lngFileSizeHigh) * 4294967296@ _
+ 2147483648@ + CCur(lngFileSizeLow)
Else
MergeDWORD = CCur(lngFileSizeHigh) * 4294967296@ _
+ CCur(lngFileSizeLow)
End If
End Function
' クラスタサイズの倍数に切り上げる
Function RoundUp(curFileSize As Currency, lngClusterSize As Long) As Currency
Dim curMod As Currency ' 余り
curMod = curFileSize Mod lngClusterSize
If curMod <> 0 Then
RoundUp = curFileSize + (lngClusterSize - curMod)
Else
RoundUp = curFileSize
End If
End Function
GetDiskFreeSpace関数について
・Windows 95(OSR2以前)では、正しい値を返しません。
・将来的に使えなくなる場合があります。(Vistaは、OK)
詳しくは、下記を参照
http://msdn.microsoft.com/ja-jp/library/cc429305 …
GetCompressedFileSize関数について
・ファイルを圧縮している場合は、GetCompressedFileSize関数を使う必要があります。
・ファイルサイズがクラスタサイズより小さいと、もとのファイルサイズのままなのでクラスタサイズに切り上げる処理を入れてます。
・95系のOSではサポートしていないので、バージョンのチェックを入れています。
No.4
- 回答日時:
こんばんわ takao0429 さん
はい。まぁそれは良いでしょう。実は貴方のために苦心してサンプルソースを考えました。
・・・。すいません前言をやっぱり訂正します。私の興味本意と前回ちょっと適当にクラスタ算出がうまくいかなかったものがなんだか自分に負けた気がしたので遊びで少しロジックを変更して遊んでいたのです。
そうそう貴方はFileSystemObjectを扱えるんでしたね。なので遊びでできたもののうちFileSystemObjectを使って算出するソース張りましょう。あぁ大切な事を言うのを忘れていました。
今からはるソースはVBのソースではなくVBSのソースです。なぜって?
テキストエディタなら何処にでもあるのでいい暇つぶしができるからです。
今から貼るソースをテキストエディタを開いて「test.vbs」と名前をつけて保存してください。
"c:\work"の部分は貴方の好きなフォルダを指定してください。
clustersize は標準値です。貴方のPCのクラスタサイズを私は知りません。
[test.vbs]
treeroot = "c:\work": patharray = Array(treeroot): clustersize = 4096: Set fso = CreateObject("Scripting.FileSystemObject")
For Each fl In fso.GetFolder(treeroot).Files
If fl.Size Mod clustersize Then diskfoldersize = diskfoldersize + (Fix(fl.Size / clustersize) * clustersize + clustersize) Else diskfoldersize = diskfoldersize + fl.Size
Next
Do While 1
temp = "": ReDim patharray2(UBound(patharray)): For i = 0 To UBound(patharray)
Set gf = fso.GetFolder(patharray(i)): fn = "": For Each fl In gf.subfolders: fn = fn & fl.Name & "\": Next: If InStr(fn, "\") > 0 Then patharray2(i) = Split(Left(fn, Len(fn) - 1), "\") Else patharray2(i) = Array("")
For j = 0 To UBound(patharray2(i))
If patharray2(i)(j) = "" Then Exit For
temp = temp & patharray(i) & "\" & patharray2(i)(j) & "/": For Each fl In fso.GetFolder(patharray(i) & "\" & patharray2(i)(j)).Files
If fl.Size Mod clustersize Then diskfoldersize = diskfoldersize + (Fix(fl.Size / clustersize) * clustersize + clustersize) Else diskfoldersize = diskfoldersize + fl.Size
Next: Next: Next: If temp = "" Then Exit Do Else patharray = Split(Left(temp, Len(temp) - 1), "/")
Loop
MsgBox diskfoldersize
さてどうでしょうか?実行してみましたか?
そのフォルダを右クリックしてディスク上のサイズと比較してください。同じ値になっている事でしょう。
オーバーフローした?ならきっと2GBを超えるフォルダを指定したんでしょうね。
あぁ…それにしても見づらい。何が書いてあるかわかりません。
貴方の為に書いたとやっぱり言えませんね。最初に言いましたがこれは遊びでできたものです。これは「FileSystemObjectを使ってもディスク上のサイズを取得できます」というためのサンプルでありそれ以上の価値はありません。もちろん貴方がこれを改変してVBソースに直してもよいでしょう(私は気にしません)。
ただ遊びじゃないのならsubをつくりGetFolderオブジェクトを渡すような再帰的処理にしたほうが綺麗なソースになりますね(CPUは食うかもしれませんが)。
1番さんの補足となりますが私が覚えている限りGetDiskFreeSpaceは2GBを超えると信用性のある値が返らなかったと思いますが…。
まぁ恐らくFAT32あたりの関係でしょうね(知識からの推測ですので間違いかもしれませんが)。
あまぁそもそもGetDiskFreeSpaceExができたせいでGetDiskFreeSpaceはいつ廃止またはサポートされるなくなるかわからないものだったと思います。
No.3
- 回答日時:
圧縮ファイルを使用している場合は、GetCompressedFileSize関数と
クラスタサイズに切り上げる方法の両方に対応する必要がありそう
ですね。
ちなみに、クラスタサイズは、GetDiskFreeSpace関数を使えば
計算することができます。
No.2
- 回答日時:
こんばんわ takao0429 さん
まずファイルサイズとディスク上のサイズこれはなんだかわかりますか?
この差の事をクラスタギャップといいます。
そしてこのクラスタとは書き込みの最小単位です。
通常fsoなどではファイル自体のサイズを返します。きっとfsoを考えた方が面倒だったのでしょう(きっと違うでしょう)。
実際考えると面倒です。まぁでも実際に1番さんの言うとおり計算しましょうか
何が面倒でしょうか?それはクラスタはOSやフォーマット形式などにより1クラスタ数が変動するという点にあります。
3.51よりも前のバージョンの Windows NT では NTFS ファイル圧縮がサポートされていないためクラスタのサイズが大きくなります。たとえば
windows95(FAT形式)ならば1クラスタ32KB 1セクタ512Bで64セクタ
windowsXP(NTFS形式)ならば1クラスタ4KB 1セクタ512Bで8セクタ
となります。
ここまでは分かりましたね?ん?よく分からない?
ハードディスクの構造上トラックをセクタで分割していますさらにセクタを分割したのがクラスタです。
そうですね取りあえずOS依存等はマイクロソフトにでも行けば分かります。
http://support.microsoft.com/kb/140365/JA/
さてではどうやって計算しましょうか?
まぁ仮にXPで普通にNTFS形式なら1クラスタは512x8=4096Bです。
クラスタで分割しあまりがあった場合1クラスタ分の要領を加算します。
ためしに簡単にVBSで作ってみたんですがやはりフォルダ内のファイルすべてを列挙しないとだめな様で結構な誤差が結構でました。
もっと処理を詰めねばならない用です面倒ですね。実感しました。
(まぁ処理を詰めても良いでしょうが)さて困りました。まぁ待ってください。之を算出してるのwindowsです。ここで思い至ります。win32APIなんか処理ないのかな・・と。
GetCompressedFileSize
http://msdn.microsoft.com/ja-jp/library/cc429287 …
指定されたファイルがディスク上で実際に占有しているサイズをバイト単位で取得します。ファイルを格納しているボリュームが圧縮機能をサポートしていて、ファイルが圧縮されている場合、圧縮済みのサイズを取得します。
なんだありました。では之で問題解決ですね。
貴方は小難しいクラスタ計算をするかwin32APIを扱えるソースを記述すればこの問題は解決します。
貴方の技量がどれほどあるかは分かりません。ですが上記二つのいづれかの方法をとればフォルダのディスク上のサイズを取得するできる事はわかったでしょう(ソースがほしいと言う場合はこの議題とはまた別件でしょう)。
No.1
- 回答日時:
FileSystemObjectのFolderオブジェクトには、ディスク上のサイズを
求めるプロパティはないので、個々のファイルのサイズを調べて
クラスタサイズの倍数に切り上げて、その合計を計算する必要が
あるのではないかと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) outlook マクロが終了しません。 1 2022/09/02 11:14
- Visual Basic(VBA) VBA This Workbookモジュールを別ファイルにコピーする方法 1 2022/09/14 01:51
- Visual Basic(VBA) VBAが止まります。 2 2022/09/02 14:02
- docomo(ドコモ) ストレージの空き領域があんまりないみたいな 5 2023/01/31 18:54
- 面接・履歴書・職務経歴書 バイトに応募して、履歴書をメールで送ってくださいと言われメールで送ったのですが、送信済みフォルダに送 4 2023/04/30 16:16
- Excel(エクセル) VBA フォルダ見える化のコードについて 2 2023/06/19 15:04
- Windows 10 この現象も、Microsoft Explorer のお粗末な仕様のためか? 2 2023/06/09 15:06
- Excel(エクセル) フォルダ内のワードファイルをPDFに一括変換するVBA 3 2023/06/09 16:51
- Excel(エクセル) Excel グラフのプロットエリアについて 2 2022/08/26 18:12
- Visual Basic(VBA) Excel VBAについて、 フォルダ内のファイルを全て開きたい場合、 FSOを使えば、Dirは使わ 1 2023/01/27 13:18
このQ&Aを見た人はこんなQ&Aも見ています
-
餃子を食べるとき、何をつけますか?
みんな大好き餃子。 ふと素朴な疑問ですが、餃子には何をつけて食べますか? 王道は醤油とお酢でしょうか。
-
「平成」を感じるもの
「昭和レトロ」に続いて「平成レトロ」なる言葉が流行しています。 皆さんはどのようなモノ・コトに「平成」を感じますか?
-
ホテルを選ぶとき、これだけは譲れない条件TOP3は?
ホテルを探す時、予約サイトで希望条件の絞り込みができる便利な世の中。 あなたは宿泊先を決めるとき「これだけは譲れない」と思う条件TOP3を教えてください。
-
【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
【お題】 ・買ったばかりの自転車を分解してひと言
-
【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
【お題】 ・急に朝起こしてきた母親に言われた一言とは?
-
ディスク上のサイズを確認する方法
Windows 7
-
Long型で表現できないファイルサイズへの対応
Excel(エクセル)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・ハマっている「お菓子」を教えて!
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
あるフォルダの中にあるファイ...
-
VBA:特定の文字を含むフォルダ...
-
C ファイル出力で、フォルダが...
-
この場合のWindows用語を教えて...
-
複数選択フォルダの配列への格納
-
ファイル名に特定の文字列を含...
-
outlook マクロが終了しません。
-
Windows10でコマンドプロンプト...
-
ファイル名と同名のフォルダを...
-
【EXCELマクロ】サブフォルダ内...
-
【マクロ】ファイル名の日付に...
-
[VBS] Unicodeの文字化けを防ぎ...
-
VBS サブフォルダの再帰処理に...
-
Access VBA で フォルダ権限...
-
FileSystemObjectの質問 最後
-
マクロVBAのフォルダ階層別で検...
-
エクセルのマクロについて質問...
-
.htaccessでのアクセス制限につ...
-
Excelのハイパーリンクについて...
-
複数の不特定のサブフォルダに...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Windows10でコマンドプロンプト...
-
Excelのハイパーリンクについて...
-
デスクトップの画像をhtmlに表...
-
VBA 最新のフォルダ取得
-
ファイル名と同名のフォルダを...
-
excelマクロ 冒頭3文字が一致す...
-
会社のネットワーク上のファイ...
-
フォルダ内のPDFファイル名を変...
-
Access VBA で フォルダ権限...
-
VBA フォルダ名に特定の文字を...
-
【マクロ】ファイル名の日付に...
-
フォルダを開いて、閉じるのプ...
-
パス名に2バイト文字(マルチバ...
-
カレントフォルダって?
-
保存先のフォルダ名を指定した...
-
Excelで指定したフォルダに保存...
-
Debug フォルダは消していいの?
-
ExcelのVBAでフォルダ指定がで...
-
C ファイル出力で、フォルダが...
-
ExcelVBAでフォルダへのハイパ...
おすすめ情報