
ただ今、エクセルのvbaを使って
複数の写真ファイルを一気に貼り付けてJPEGに変換するプログラムを作っています。
だいたいはできたのですが、一つ壁にぶつかりました。
アルゴリズムは指定したフォルダのファイル名を取得し、それをリスト用のシートに出力し、使用者に必要なファイルを取捨選択してもらうようにしています。
フォルダのファイル名は下記URLのサンプルから使わせていただいています。
http://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub0 …
しかし、これを使うと、
「1.jpg、2.jpg~10.jpg・・・」のファイル名を取得すると、
「1.jpg、10.jpg、2.jpg・・・」
という風になります。これを回避するには現状「01.jpg、02.jpg~10.jpg・・・」と名前をつけるしかないのですが、不特定多数の人に使わせるので、出来るだけ汎用性を持たせたいと思っています。
例えば
「テスト1-1.jpg、テスト1-2.jpg~テスト1-10.jpg・・・
テスト10-1.jpg、テスト10-2.jpg~テスト10-10.jpg・・・
テスト11-1.jpg、テスト11-2.jpg~テスト11-10.jpg・・・」
というファイル名を上の通りに並べ変えるとしたら、どうすればいいでしょうか?
難しい場合は
「01.jpg、02.jpg~10.jpg・・・」
の時だけでもいいのでよろしくお願いします。

No.2ベストアンサー
- 回答日時:
Windows XP 以降、エクスプローラーのファイル表示に使われているソート ルールってことですよね。
(マイクロソフトの直観的なソート)StrCmpLogicalW って API を使ってるっぽいです。
SortByIntuitiveFilename っていう関数を作ってみました。
文字列型の配列にファイル名の一覧を入れておいてこの関数に渡せばソートしてくれます。
一応テスト用のプロシージャ Sub Test() も載せておきます。
Option Explicit
Declare Function StrCmpLogicalW Lib "SHLWAPI.DLL" (ByVal lpStr1 As String, ByVal lpStr2 As String) As Long
Sub SortByIntuitiveFilename(ByRef aFiles() As String)
Dim i As Long
Dim j As Long
Dim tmp As String
'Dim minIdx As Long
'Dim maxIdx As Long
'minIdx = LBound(aFiles)
'maxIdx = UBound(aFiles)
For i = LBound(aFiles) To UBound(aFiles)
For j = i To UBound(aFiles)
If StrCmpLogicalW(StrConv(aFiles(i), vbUnicode), StrConv(aFiles(j), vbUnicode)) > 0 Then
tmp = aFiles(i)
aFiles(i) = aFiles(j)
aFiles(j) = tmp
End If
Next
Next
End Sub
Sub test()
Dim strPath As String
strPath = "e:\test"
Dim fso As Scripting.FileSystemObject
Dim fld As Scripting.Folder
Set fso = New Scripting.FileSystemObject
Set fld = fso.GetFolder(strPath)
Dim fileNames() As String
Dim cnt As Long
cnt = fld.Files.Count
ReDim fileNames(cnt - 1)
Dim k As Long
k = 0
Dim f As Scripting.File
For Each f In fld.Files
fileNames(k) = f.Name
k = k + 1
Next
Call SortByIntuitiveFilename(fileNames)
End Sub
ありがとうございます!
これは、便利ですね。
StrCmpLogicalW という関数の仕様が見つからなかったので、ちょっと試してみた感じだと、XPのファイルシステムを使って二つのファイル名が降順だと1、同じなら0、昇順なら-1を返すってかんじっぽいですね。
これなら、XPのエクスプローラーとまったく同じ順序になるので、違和感もなくなると思います。
ありがとうございましたー
No.3
- 回答日時:
ソートキーのためにシートの各行(ファイル名が入っている)の余分な空き列に、Format関数ででも、1や2を001,002に変換した文字列を作って持ち(12,23も012,023のようにする)、この列でエクセルでソートして、ソート後の結果を使えば良い、
作業列が嫌いなら配列に一時的にファイル名を持つ必要があるが、配列データのロジックも色々有り、テストも本来大変。
ーー
エクセルではシートのセルにあるデータ(内容)でしかソートできない。色々悩んでよい方法がないか、など考えても無駄。
ーー
ソートするルールは決っているのだ。それを勉強して、ユーザー(VBA内を作るもの)がそれに合うように修正ソートキーをどこかに作らざるをえないのだ。
ーーー
ーを挟んでも質問尾ことは解決されないのでは。桁調節のスペースが許されないケースでは。
回答ありがとうございます!
「ーを挟んでも質問尾ことは解決されないのでは。桁調節のスペースが許されないケースでは。」
ハイフンとかいれた場合の質問をしても、質問箱では解決できないということですか?
又、format関数を用いた作業列を使うなら、ハイフンが邪魔で桁調整ができないということですかね。
format関数すら、この答えで知ったものですから私には難しいですが、桁調整の問題はNo.1番さんの答えで解決しました(ついでに作業列もありません)
しかし、format関数を使った作業列という案も十分な有効な策なので、どちらがいいかは吟味させていただきます
No.1
- 回答日時:
仮にA2以下に書き出されたファイル名をソートする場合、
Sub try()
Const MX As Long = 5 '取り敢えず各数値最大5桁の設定
Dim target As Range '並べ替え対象セル範囲
Dim r As Range 'Loop用
Dim rep As String 'Format関数用
Dim tmp As String '整形前Value
Dim ret As String '整形後Text
Dim s As String '文字1個
Dim ss As String '連続数値文字
Dim x As Long 'Len
Dim p As Long '桁数記憶用
Dim i As Long
Dim j As Long
Application.ScreenUpdating = False
'並べ替え対象のセル範囲をセット。
'サンプルとして(A2:A列最終行)
Set target = Range("A2", Cells(Rows.Count, 1).End(xlUp))
rep = String(MX, "0")
For Each r In target
tmp = r.Value
x = Len(tmp) + 1
'整形後Text長をMAXで設定
ret = Space(x * MX)
p = 0
j = 1
'1文字ずつLoop
For i = 1 To x
s = Mid$(tmp, i, 1)
If IsNumeric(s) Then
'数値だったら連続数をCountして連結
p = p + 1
ss = ss & s
Else
If p > 0 Then
'Format関数で桁合わせて連結
Mid$(ret, j, MX) = Format$(ss, rep)
j = j + MX
p = 0
ss = Empty
End If
'数値以外を連結
Mid(ret, j, 1) = s
j = j + 1
End If
Next
'整形後Textをふりがなにふる
r.Phonetic.Text = Left$(ret, j)
Next
'ふりがなSort
target.Sort Key1:=target.Item(1), Order1:=xlAscending, _
Header:=xlNo, OrderCustom:=1, _
MatchCase:=False, Orientation:=xlTopToBottom, _
SortMethod:=xlPinYin
Application.ScreenUpdating = True
Set target = Nothing
End Sub
..こんな感じで。
地道Loop案なのでちょっと遅いかもしれませんが。
ありがとうございます!
ふりがなを設定すると、エクセルの既存の機能で、並び替えできるようになるんですか・・・
これは知らなかった。ふりがなってバカにできないですねぇ
勉強になります
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) Excel 毎日手作業で時間がかかって、泣きたいです、、、VBAのプロの方、助けてください。。。 3 2022/10/25 04:26
- PHP 画像ファイルの名前をそのままURLにする 3 2022/10/16 11:18
- Visual Basic(VBA) 【VBA】写真の縦横比を変えずに貼り付ける 5 2023/06/13 11:42
- その他(ソフトウェア) 画像のファイル形式、拡張子が変わると、性能が変わると思うのですが、ファイル名の「jpg、png、do 8 2022/08/10 13:37
- その他(パソコン・スマホ・電化製品) 拡張子の選択方法について 4 2022/09/22 22:04
- PHP $filePath = './user_img/' . $file['name'];? 1 2022/12/10 07:29
- Excel(エクセル) excelで検索した商品の画像(ネットワーク上の)を表示させたい。 3 2023/06/28 00:32
- デジタルカメラ 写真のファィル形式について 4 2022/10/12 14:18
- Windows 10 JPG PNG サポートされていない形式 (JPGファイルで開ける、開けないがある場合) 4 2022/04/23 13:46
- PDF pdfファイルのjpgファイルへの変換 5 2022/06/03 10:13
このQ&Aを見た人はこんなQ&Aも見ています
-
Dir関数で読み取り順を操作できる?
Visual Basic(VBA)
-
EXCELのVBAで画像を選んだ順に貼り付ける方法
Excel(エクセル)
-
VBA ソートすると、1、11、2,3になって・・
Excel(エクセル)
-
-
4
VBAでエクセルシートを更新(リフレッシュ)する方法を教えて下さい。
Excel(エクセル)
-
5
(VBA) Dir 関数で取得するファイル一覧の順序
PowerPoint(パワーポイント)
-
6
VBA フォルダ内のファイルを、ファイル名順に開く
その他(Microsoft Office)
-
7
VBAでセルを指定した画像のコピー&ペーストを繰り返したい
Excel(エクセル)
-
8
System.IO.Directory.GetFilesの順番
Visual Basic(VBA)
-
9
マクロを実行すると画像がズレてしまいます
その他(Microsoft Office)
-
10
フォルダ内の全てのファイルを降順で並べ替え
Excel(エクセル)
-
11
任意フォルダから画像をすべてエクセルの指定マスに貼り付けをしたい
Visual Basic(VBA)
-
12
Excel.VBA テキストファイルを指定行数からの読み込む
Excel(エクセル)
-
13
エクセルのセルに指定画像(.jpg)を自動で貼り付けたいです。
Excel(エクセル)
-
14
【ExcelVBA】300万件越えCSVから条件を満たす行だけ抽出するには?
Visual Basic(VBA)
-
15
Excel VBA マクロ ファイル名ソート
Visual Basic(VBA)
-
16
VBAでパワーシェルを実行したいのですが、なかなかうまく出来ず、有識者の知識をお借りさせてください。
その他(プログラミング・Web制作)
-
17
【VBA】写真の縦横比を変えずに貼り付ける
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
System.IO.Directory.GetFiles...
-
配列の問題
-
C# DataGridView のヘッダーセ...
-
VB.NETでファイル名順にファイ...
-
qsortについて
-
VBA基本構文の作り方 2列の...
-
配列内のデータのソート
-
SORTについて
-
コレクションの数値をSortで並...
-
構造体配列のソート
-
FFFTPでフォルダをABC順になら...
-
C# DataTable ソートについて
-
質問>>ダイレクトXをはじめよ...
-
プログラミングについて 配列を...
-
10個の整数を入力して小さい順...
-
C# DataTableの行をソートしてD...
-
C# DataGridViewのソート
-
STLのlistのソートについて教え...
-
4番目以降の並べ替え
-
PHPでファイル一覧を取得して開...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
System.IO.Directory.GetFiles...
-
C# DataGridView のヘッダーセ...
-
VBA基本構文の作り方 2列の...
-
C言語・要素除去
-
C# DataTableの行をソートしてD...
-
VB.NETでファイル名順にファイ...
-
構造体配列の並べ替え
-
あるディレクトリ内のファイル...
-
配列の問題
-
10個の整数を入力して小さい順...
-
2次元配列を複数項目でソートし...
-
構造体のリストをソートしたい。
-
DataGridViewソート時に先頭行...
-
DataGridViewのソートを止めたい
-
datagridviewの並べ替え
-
C++ 入力した3つのint型の整数...
-
DataGridViewの複数列を連動し...
-
Excelですべての組合せ(重複組...
-
C#のリストボックスで、クリッ...
-
VBScriptで重複レコードを削除...
おすすめ情報