質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.36%

  • VBA

    1122questions

    VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Dir関数の呼び出しでファイル名の昇順にマッチングしたい

解決済

回答 3

投稿 2017/11/30 11:06 ・編集 2017/11/30 16:20

  • 評価
  • クリップ 0
  • VIEW 93

Taishi2002

score 3

フォルダ内にFILENAMEyyyymmddHHMMSS.txtという名前のテキストファイルが複数あり、ファイル数が100個を超えた場合日付が古いものを消すロジックを実装したいです。

そのため以下のようなコードで実装していますが、Dir関数で返るファイル名がファイル名の昇順になりません。
これを操作することは出来ないでしょうか?

    'バックアップフォルダー内のファイル数をカウント
    Dim intFileCNT As Integer
    intFileCNT = 0
    Dim strBackupFileName As String
    strBackupFileName = Dir("フォルダパス")
    While strBackupFileName <> ""
        If Left(strBackupFileName, 8) = "FILENAME" Then
            intFileCNT = intFileCNT + 1
        End If
        strBackupFileName = Dir()
    Wend

    '古いバックアップファイルの削除
    strBackupFileName = Dir("フォルダパス")
    While intFileCNT > 100                  '最大保存ファイル数は100個
        If Left(strBackupFileName, 8) = "FILENAME" Then
            Call Kill("フォルダパス" & strBackupFileName)
            intFileCNT = intFileCNT - 1
        End If
        strBackupFileName = Dir()
    Wend
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

ディスクのフォーマット形式によって取得順は異なるようです。
http://officetanaka.net/excel/vba/file/file07.htm

なので現状通りDir関数を使うのであれば、一旦取得結果を配列に格納してから、自力ソートするしかないと思います。

Dir関数ではなくFileSystemObjectを使うとソートは可能なようですが、コーディングにひと手間必要です。
とは言っても難しくはないと思います。
詳しくはこちらを参照。
https://kuroeveryday.blogspot.jp/2013/10/FileSystemObjectSort.html

追記
Dir関数で行うということでしたので、ソート処理について追記しておきます。
ファイル名をため込むのには、配列を使うよりもArrayListを使うと便利です。
とりあえずバックアップフォルダー内の処理だけ書き換えてみましたので参考にどうぞ。

    Dim intFileCNT As Integer
    Dim strFileName As String
    intFileCNT = 0

    'バックアップフォルダー内のファイル数をカウント
    Dim strBackupFileNames As Object
    Set strBackupFileNames = CreateObject("System.Collections.ArrayList")
    strFileName = Dir("フォルダパス")
    While strFileName <> ""
        strBackupFileNames.Add strFileName
        If Left(strFileName, 8) = "FILENAME" Then
            intFileCNT = intFileCNT + 1
        End If
        strFileName = Dir()
    Wend
    strBackupFileNames.Sort

    ' 確認
    For Each tmp In strBackupFileNames
        Debug.Print tmp
    Next

投稿 2017/11/30 11:22

編集 2017/12/01 08:54

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/30 19:59

    ありがとうございます。
    FileSystemObjectでも良さそうですが、Dir関数で一通り取得した後に自力ソートしてみます。

    キャンセル

  • 2017/12/04 14:03

    重ね重ねありがとうございます。
    VBAから.NET Framework クラス ライブラリの機能の一部を使用できるのですね。
    勉強になりました。

    キャンセル

+1

Dirの出力順をなんとかする事は出来ない(多分物理順)ので、ソートするしかないですね。
配列のソート関数とかは無いと思うので、自分でソート処理を書く事になるかと。取得する度に、位置を決めてずらすんでしょうか。

変数宣言を省略するとこんな感じか。

n = 1
files(0) = Dir("*")
Do
    file = Dir()
    If file = "" Then Exit Do
    For i = 0 To n - 1
        If file < files(i) Then
            For j = n - 1 To i Step -1
                files(j + 1) = files(j)
            Next
            Exit For
        End If
    Next
    files(i) = file
    n = n + 1
Loop
For i = 0 To n - 1
    Debug.Print files(i)
Next

投稿 2017/11/30 11:15

編集 2017/11/30 12:50

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/30 17:41

    ありがとうございます。
    For j = n - 1 To i Step -1
    という部分はどういう意味なのでしょうか。

    キャンセル

  • 2017/11/30 20:40

    うーむ、見た通りの意味なのですが。

    キャンセル

  • 2017/12/04 13:50

    Step -1がよくわかっていませんでしたが、要素数の大きいものから処理するということなんですね。

    キャンセル

+1

前に同じ内容で困った時にどなたかのHPで教えて頂いた
「StrCmpLogicalW」で、エクスプローラに近いソートができたような。

ひょっとしたら環境によって異なるのかもですが。。。

Declare Function StrCmpLogicalW Lib "SHLWAPI.DLL" (ByVal lpStr1 As String, ByVal lpStr2 As String) As Long

Public Function SortByIntuitiveFileName(ByRef PathAry As Variant)
'+ エクスプローラで表示されている順に

    Dim i           As Long
    Dim j           As Long
    Dim TempPath    As String
    Dim ConvAry()   As String

    If IsArray(PathAry) = False Then Exit Function

    ReDim ConvAry(LBound(PathAry, 1) To UBound(PathAry, 1))

    For i = LBound(PathAry, 1) To UBound(PathAry, 1)
        ConvAry(i) = StrConv(CStr(PathAry(i)), vbUnicode)
    Next

    For i = LBound(PathAry) To UBound(PathAry)

        For j = i To UBound(PathAry)

            If StrCmpLogicalW(ConvAry(i), ConvAry(j)) > 0 Then

                TempPath = PathAry(i)
                PathAry(i) = PathAry(j)
                PathAry(j) = TempPath

            End If

        Next

    Next

End Function

投稿 2017/11/30 12:12

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/04 13:47

    ありがとうございます。
    エクスプローラの特殊なソートが使える関数があるんですね。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.36%

関連した質問

同じタグがついた質問を見る

  • VBA

    1122questions

    VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。