[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『RENAMEで使えない文字列』(パンチ)
VBAで変名(RENAME)する場合、ファイル名に特定文字列が存在すると変名できない場合があります。
以下のサイトで使えない文字列がリストアップされています。
http://tanaka-misaki.blogspot.com/2012/02/excel-vba.html
今回変名中にチルダ(〜)があると同じく変名できない事例が判りました。
他に利用できない文字列がありますか ?
あれば、先に知っておきたいです。
< 使用 Excel:Excel2021、使用 OS:Windows11 >
私の手元では再現しませんでした。~ を使った Renameができました。 Sub test() Name "D:\MyDocuments\202308\test1.xlsm" As "D:\MyDocuments\202308\~test1.xlsm" End Sub
恐縮ですが、エラーが再現できるコードを教えていただけますか?
(xyz) 2023/08/06(日) 12:30:25
長さ制約とか、開かれているファイルを変更しようとしている、とかではないですか?
(xyz) 2023/08/06(日) 12:53:35
F8でトレースすると、ローカルウインドウ中のFileNameの値が
チルダの部分が?と表示されるので変名できない
試しに、ForbiddenChars = "/\:*?<>|[]"の最後にチルダを追加しようとしても
?と表示される。
長さ制約とか、開かれているファイルを変更しようしている訳ではありません。
Option Explicit
Sub RenameFiles()
Dim folderPath As String Dim FileName As String Dim CheckedFileName As String Dim newName As String Dim targetString As String Dim ForbiddenChars As String Dim i As Long
' 指定ディレクトリのパス folderPath = "C:\Users\Tommy\Temp\"
'ダメ文字 ForbiddenChars = "/\:*?<>|[]"
' ディレクトリ内のファイルをループ処理 FileName = Dir(folderPath & "*")
Do While FileName <> ""
For i = 1 To Len(ForbiddenChars) CheckedFileName = Replace(FileName, Mid(ForbiddenChars, i, 1), "_") Next i
Name folderPath & CheckedFileName As folderPath & FileName
FileName = Dir Loop
End Sub
(パンチ) 2023/08/06(日) 12:58:22
ありがとうございます。
チルダのように見えてチルダではないのでは? A1セルにコピーして、=CODE(A1)とするとどんな結果になりますか? =UNICODE(A1)はどうなりますか? チルダなら いずれも126が返ります。
ユニコードにしかない(Shift_JIS未対応の)文字は、 VBEでは表示できませんし、 Nameステートメントだと変換できないと思います。 FSOのMoveFileメソッドを使うとよいでしょう。
(xyz) 2023/08/06(日) 13:26:30
=UNICODEでは12316と表示されました。
(チルダに見えてチルダでない文字のようです。)
現在のNameでは、使えない文字列の場合は
MoveFileを利用するとエラーが出ないであれば変更したいのですが
現在のコードをどう変更すべきかなるべく簡単な参照先ありますか ?
FSO(FileSystemObject)で検索すると間口が広すぎます。
(パンチ) 2023/08/06(日) 13:55:46
(もこな2) 2023/08/06(日) 14:01:58
「リネームという目的から考えればそいつは対象外ですよね?」
なぜ、リネーム対象外のファイルと決めつけるのかは理解できませんが
私に取っては、リネーム対象のファイルの一つです。
今回は、たまたま「チルダに見えてチルダでない文字」が問題になりましたが
他にもこのようなダメ文字がある事は考えられると推察されます。
既にダメ文字が混在するファイル名でもファイル名としては見えてるがVBAで
RENAMEしたくてもダメ文字があるのでファイル名の一部が?となり処理できない。
最初から、「チルダに見えてチルダでない文字」だけがダメ文字であれば
対象外で処理から逃げれば良いのでしょうが、はたしてこの文字だけが
ダメ文字なのでしょうか?
xyzさんの回答では、ユニコードにしかない(Shift_JIS未対応の)文字は、
VBEでは表示できませんとあるので他にも?になる文字列が存在するはずですよね。
(パンチ) 2023/08/06(日) 14:34:35
>リネーム対象外のファイルと決めつけるのかは理解できません
決めつけてるんじゃなくて【興味本位】でどういうものを想定しているかという話でした。
(私の感覚だと本来のファイル名としてそういった名前を付けませんので)
>xyzさんの回答では、ユニコードにしかない(Shift_JIS未対応の)文字は〜
そちらに言及する意図はありませんでした。
※水掛け論になりそうなのでお返事は不要です。
(もこな2) 2023/08/06(日) 15:23:33
フォルダーを移動せずに、名前を変更するだけなら、Nameプロパティを使えばいいですね。
とりあえず下記をご参考に。
Office TANAKA - FileSystemObject[Nameプロパティ] http://officetanaka.net/excel/vba/filesystemobject/file06.htm
(hatena) 2023/08/06(日) 15:39:08
Shift_JIS - Wikipedia
https://ja.wikipedia.org/wiki/Shift_JIS
上記によるとShift_JISは、11438文字
Unicode - Wikipedia
https://ja.wikipedia.org/wiki/Unicode
上記によると最新のバージョンでは、149,186文字
差し引きすると、13万文字以上が該当することになります。
それを逐一調べるというのは現実的ではないですね。
FileSystemObjectならUnicode対応なので問題なくリネームできるはずです。
(hatena) 2023/08/06(日) 16:01:16
説明不足でしたか。
(1)VBE(VBAのエディタ画面)はユニコード未対応なので、 Shift_JISに無い文字を直接的に入力・表示することができません(?となる)。 ただし、回避策は色々あります。 ・文字コードがわかれば、例えば ChrW(12316)とすることで、その全角チルダみたいなのも 扱えます。(下記、test2 参照) ・ワークシートの値はもちろんユニコード対応なので、A1セルにその文字を入力しておいて Range("A1").Valueと参照すれば、実質的に画面上で扱えることになります。
(2)Nameでは変名できないものも、FSO.MoveFileでは可能です。 下記test2を参照してください。
(3)Shift_JIS未対応のユニコード文字は無数(少なくとも10個や20個ではないです)にありますから、 少なくとも限定列挙して予め変更しておくというのは無理ではないでしょうか。 (どなたか簡単な対応策をお持ちかもしれませんが。)
実際に変名するときには、具体的に変更したいファイル名が明確になっているでしょうから、 少なくとも上記の(1)(2)を考慮すれば、その都度の対応でなんとかなるように思いますが、 いかがですか?
Sub test2() Dim s1$, s2$ s1 = "D:\MyDocuments\202308\" & ChrW(12316) & "test1.xlsm" s2 = "D:\MyDocuments\202308\~test1.xlsm"
Dim FSO As Object Set FSO = CreateObject("Scripting.FileSystemObject")
'Name s1 As s2 'これはエラーになります FSO.MoveFile s1, s2 'これはOKです。 End Sub
(xyz) 2023/08/06(日) 16:07:45
回答コメントを拝見せずにコメントしておりました。ありがとうございます。
確かにFSOのNameのほうがこの場合は適切のようですね。 (一つしか覚えられない"海馬縮小ぎみ"の私は、MoveFileでなんでもすまそうとしていました)
また文字コードの数を示していただいたので、分かりやすいです。
(xyz) 2023/08/06(日) 16:34:33
ちなみに、filesystemobjectについては、下記が便利かもしれません。 http://officetanaka.net/excel/vba/filesystemobject/index.htm
↑は辞書みたいなものなので、もう少しその前からということなら、 ネットを検索すると色々と記事があると思います。 ファイルやフォルダを扱う機会が増えるとすれば、 色々と応用が利く場面もあるでしょう。 是非一読して、こんなことができるんだね、と目を通しておいて、 実際には利用の都度参照すればいいですよ。
(xyz) 2023/08/06(日) 16:57:57
149,186文字もあるならFSOのMoveFileを利用しないと対応できないのは明らかですね。
XYZさん、アドバイスありがとうございます。
FSOを利用するコードを試行錯誤してしていますが
「チルダに見えてチルダでない文字」が存在しても?にはならないで
変名できそうなコードが出来そうだと思いましたが
以下のコードでエラーが出ました。
なぜエラーが出るか判りますか ?
FSO.movefiles folderPath & FileName, folderPath & newName
実行エラー / オブゼクトは、このプロパティ又はメソッドをサポートしていません。
newNameは、思ったようなファイル名になっているのをローカルウインドウで確認済みです。
Sub RenameFiles()
Dim folderPath As String Dim FileName As String Dim CheckedFileName As String Dim newName As String Dim targetString As String Dim ForbiddenChars As String Dim i As Long
Dim R As VbMsgBoxResult
Dim FSO As Object Set FSO = CreateObject("Scripting.FileSystemObject")
' 指定ディレクトリのパス folderPath = "C:\Users\Tommy\Temp\"
'ダメ文字 ForbiddenChars = "/\:*?<>|[]"
' 特定文字列 targetString = " CaseNo"
' ディレクトリ内のファイルをループ処理 FileName = Dir(folderPath & "*")
Do While FileName <> ""
For i = 1 To Len(ForbiddenChars) CheckedFileName = Replace(FileName, Mid(ForbiddenChars, i, 1), "_") Next i
Dim CHK As Integer
If CheckedFileName <> FileName Then FSO.movefiles folderPath & FileName, folderPath & CheckedFileName CHK = 1 Else CHK = 0 End If
' 特定文字列が含まれる場合にファイル名を変更 If InStr(CheckedFileName, targetString) > 0 Then newName = Left(CheckedFileName, InStr(CheckedFileName, targetString) - 1) newName = newName & ".txt" If CHK = 1 Then FSO.movefiles folderPath & CheckedFileName, folderPath & newName Else FSO.movefiles folderPath & FileName, folderPath & newName End If End If FileName = Dir Loop
MsgBox "変名終了。" End Sub
(パンチ) 2023/08/06(日) 17:25:28
MoveFileです。sは要りません。そこ以外は見ていません。
(xyz) 2023/08/06(日) 17:48:05
凡ミスの指摘ありがとうございます。
(パンチ) 2023/08/06(日) 18:18:12
解決済みのようなので蒸し返すのもアレですが、 ForbiddenChars = "/\:*?<>|[]" これらの文字は、OSの仕様上、ファイル名に使えない文字です。 なので、これらの文字をつかった名前ではファイルを保存できません なので、 FileName = Dir(folderPath & "*") としたとき、FileName にこれらの文字が含まれている事はありません このチェック処理、必要無いですよね? (´・ω・`) 2023/08/07(月) 08:56:03
[ と ] は使えますよ。(OSの仕様上だけの話なら)
(白茶) 2023/08/07(月) 09:14:02
>[ と ] は使えますよ あっと、ホントだ 逆に、" が抜けてますね
使えない理由と対応策を整理する必要があるかも (´・ω・`) 2023/08/07(月) 09:20:50
その後、色々試行錯誤しながらコードを改変中ですが完成に至りません。
考えたのは、
「チルダに見えてチルダでない文字」=Chrw(12316)などは
VBAでは"?"と表示されるので、こいつを他の文字(例えば"_")に変更すれば変名できるのではと思いましたが
最後の変名で
FSO.MoveFile folderPath & FileName, folderPath & newName
FileNameの文字列の一部に?で表示されたままなので変名できませんでした。
(そんなファイルは存在しないのでエラーは当然の結果)
完全に打つ手なしの状態です。
何とかMoveFileする方法はありませんか ?
Option Explicit
Sub RenameFiles()
Dim folderPath As String Dim newName As String Dim targetString As String Dim i As Long
Dim FSO As Object Set FSO = CreateObject("Scripting.FileSystemObject")
' 指定ディレクトリのパス folderPath = "C:\Users\Tommy\Downloads\"
' 特定文字列 targetString = " CaseNo"
' ディレクトリ内のファイルをループ処理 Dim FileName As String FileName = Dir(folderPath & "*.ts")
Do While FileName <> ""
'Filenameの文字列中にダメ文字である?をチェックして '存在する場合はアンダーバー(_)に置き換える If InStr(FileName, "?") > 0 Then ' Replace the Unicode character with an underscore newName = Replace(FileName, "?", "_") Else newName = FileName End If
' 特定文字列が含まれる場合にファイル名を変更 If InStr(newName, targetString) > 0 Then newName = Left(newName, InStr(newName, targetString) - 1)
newName = newName & ".ts" FSO.MoveFile folderPath & FileName, folderPath & newName End If
FileName = Dir Loop
MsgBox "変名終了。" End Sub
(パンチ) 2023/08/07(月) 11:47:00
過去ログですがちょっと違うかも 『ファイル名の変更』(悩める人) [[20230620133022]]
ファイル名の取得もFSOでやればよくないですか? (´・ω・`) 2023/08/07(月) 11:59:27
> FileNameの文字列の一部に?で表示されたままなので どこに表示した場合ですか? その理由は納得されたんですよね。
> 何とかMoveFileする方法はありませんか? それはできたはずじゃないですか。 そうではなくて、 Shift_JISに無い文字を"_" に置換する方法 ではないんですか?
それは全列挙はできないという話でしたよね。それは納得されたんですか?
全角チルダ擬き に限定した話なら、 あなたのコード中の "?" のところを ChrW(12316)に置き換えればOKですよ。
(xyz) 2023/08/07(月) 12:07:22
ああ、(´・ω・`)さんの Function PathString(s)を使えば解決ですね。
(xyz) 2023/08/07(月) 12:18:05
この間から、同じ質問が続いていますが、問題の元凶はファイル名を「Dir関数」で取得している事です。 「Dir関数」はEXCELにVBAが搭載されたEXCEL95時代からある関数で、レガシーな関数です。 Shift_JISで扱えない文字は 「?」U+003Fに置き換えられる仕様です。 可逆性はないので、一旦「?」に置き換わると、元に戻せません。 存在しないファイルをリネームしようとしているので、実行時エラーとなります。
なので、解決策としては、(´・ω・`)さんが指摘しているように、 現在の路線でいくなら「ファイル名の取得もFSOでやる。」です。 検索すれば、いくらでもサンプルはあるはずです。 先日、どのスレッドか失念しましたが、他の人が回答されてましたがPowerShellでやるのも一案です。
(まる2021) 2023/08/07(月) 12:52:00
おおそうでしたね。 Dir関数の限界については、ここでも何度も議論されているのに気づきませんで失礼しました。 まる2021さん、ありがとうございました。 (xyz) 2023/08/07(月) 12:57:44
ファイル名の取得もFSOでやればよくないですか?
以下のようにDIRからFSOでファイル名を取得するように変更しましたが同じ個所でエラーが出てダメでした。
(FSOでファイル名を取得してファイル名のダメ文字がローカルウインドウでは?で表示されるのは変わりありません)
' ディレクトリ内のファイルをループ処理 Dim File As Object
For Each File In FSO.getfolder(folderPath).Files Debug.Print File If Right(File.Name, 3) = "txt" Then Debug.Print File ' 特定文字列が含まれる場合にファイル名を変更 If InStr(File, targetString) > 0 Then newName = Left(File, InStr(File, targetString) - 1)
newName = newName & ".ts" FSO.MoveFile folderPath & File, folderPath & newName End If End If Next
’-------------------------------
どこに表示した場合ですか? ローカルウインドウのfileやnewFileにおいてダメ文字相当が?に変わって表示される。
あなたのコード中の "?" のところをChrW(12316)に置き換えればOKですよ。 これは、最初にやってみましたがダメなので
?に変更して試しみましたが
?とChrw(12316)を利用しても
FileNameの文字列の一部に?で表示されたままなので変名できないのは同じです。
(そんなファイルは存在しないのでエラーは当然の結果)
まる2021さん、助け舟ありがとうございます。
Shift_JISで扱えない文字は 「?」U+003Fに置き換えられる仕様です。 可逆性はないので、一旦「?」に置き換わると、元に戻せません。 存在しないファイルをリネームしようとしているので、実行時エラーとなります。
まさにこれに付きます。
XYZさんも納得されているようなのでFSOでファイル名を取得するが根幹の問題ですね。
(パンチ) 2023/08/07(月) 13:27:12
試しにFSOで取得したファイル名をセルに入れてみた場合も文字化けしているのだろうか?
なお、FSOから直接セルに入れるのといったん変数に受けてからセルに入れるのとで試してみてくれ。
あとまる2021さんが > Shift_JISで扱えない文字は 「?」U+003Fに置き換えられる仕様です。 と言っているのはあくまでもDir関数の話。 (ねむねむ) 2023/08/07(月) 13:34:35
For Each File In FSO.getfolder(folderPath).Files If Right(File.Name, 3) = "txt" Then ' 特定文字列が含まれる場合にファイル名を変更 If InStr(File, targetString) > 0 Then Range("A3") = File Debug.Print File Stop
Debug.print File
C:\Users\Tommy_\Downloads\無題-2 ?test? CseNo_123456.txt
Range("A3") ---> 「変数に受けてからセルに入れる」ですか ?
C:\Users\Tommy_\Downloads\無題-2 〜test〜 CseNo_123456.txt
「FSOから直接セルに入れる」の意味が判らなかったので実現できませんでした。
(パンチ) 2023/08/07(月) 13:49:36
たぶん目下進行中の議論とは無関係な話だろうなとは思いながら書きます。^^; 飛び交ってる言葉だけ取ると、どうにも傍目には混同してしまいそうに聞こえるので...
一般的に「ダメ文字」というと 「使おうと思っても使えない文字」ではなく、 「使えてしまうが故に問題を引き起こす文字」の事を指すと思いますので、 その辺、ニュアンス的に誤解を与えそうな言い回しです。
まさに波ダッシュと全角チルダの問題なんかがそうですね。
いまさら聞けない!波ダッシュと全角チルダ問題についてまとめてみた - Secret Garden(Instrumental)
https://secret-garden.hatenablog.com/entry/2022/05/11/212649
全角チルダ(〜)と波ダッシュ(?) | 社内SE3割増し
https://syanaise3wariup.com/zenchirunamida/
波ダッシュ・全角チルダ問題 - とほほのWWW入門
https://www.tohoho-web.com/ex/dash-tilde.html
波ダッシュ(?)と全角チルダ(〜)は違う文字 | レコチョクのエンジニアブログ
https://techblog.recochoku.jp/7538
oracleデータベース界隈では割と「そんなの常識じゃん」っぽく扱われてて(たまに)イラっとします ^^; VBAの中でそこまで問題になってるのは見かけた事ないですけど...
つまり、ファイル名にChrW(12316)とか使っちゃってる時点である意味(ゴニョゴニョ...
はい、お邪魔しました! スンマセンでした... ^^;
(白茶) 2023/08/07(月) 14:21:04
最初の質問
Nameメソッドでリネームしようとするエラーになる。
ファイル名に使えない文字が含まれているためだと思い、
その文字を置き換えてからリネームする。
実際は、ファイル名にShift_JISにないUnicode文字が含まれていて、
Dir関数(Unicode非対応)でファイル名を取得するときに?に文字化けしたため、
エラーになっていた。
そもそも、ファイル名に使えない文字が、ファイル名に含まれることはないので、
その文字を置き換える処理自体は不要、無意味なものである。
ということでとう所の質問は無意味なものであった。
途中から質問が下記に変化
特定文字列が含まれる場合にファイル名を変更したい
(Shift_JISにないUnicode文字が含まれている場合もあり)
対策
ファイル名取得、リネームにDir関数、Nameメソッドを使うのではなく、
Unicode対応のFileSystemObjectを使えばエラーなくリネームできる。
ファイル取得は、
For Each File In FSO.getfolder(folderPath).Files
リネームはMoveFile あるいは Nameプロパティで
MoveFileの場合
FSO.MoveFile folderPath & File, folderPath & newName
Nameプロパティの場合
File.Name = newName
(自分としてはNameプロパティの方がシンプルだと思うがなぜかスルー)
(hatena) 2023/08/07(月) 14:29:16
' 特定文字列が含まれる場合にファイル名を変更 If InStr(File, targetString) > 0 Then newName = Left(File, InStr(File, targetString) - 1) newName = newName & ".ts" FSO.MoveFile folderPath & File, folderPath & newName End If
下記に変更すればエラーはなくなると思う。
' 特定文字列が含まれる場合にファイル名を変更 If InStr(File.Name, targetString) > 0 Then newName = Left(File,Name, InStr(File,Name, targetString) - 1) newName = newName & ".ts" FSO.MoveFile folderPath & File, folderPath & newName End If
Nameプロパティを使うなら、
' 特定文字列が含まれる場合にファイル名を変更 If InStr(File.Name, targetString) > 0 Then newName = Left(File,Name, InStr(File,Name, targetString) - 1) newName = newName & ".ts" File.Name = newName End If
(hatena) 2023/08/07(月) 14:50:29
「ダメ文字」=>私の解釈では「使おうと思っても使えない文字」の定義については、
私が勝手にそう読んでいるだけで認識不足で世間一般では
「使えてしまうが故に問題を引き起こす文字」との事なので改めます。
ファイル名にChrW(12316)とか使っちゃってる時点でダメじゃん的なご意見ですね。
それを言われるとごもっともですが12316を使ったファイルが実際あるので
処理対象から外すと言う訳には至りません。
hatenaさん、
自分としてはNameプロパティの方がシンプルだと思うがなぜかスルー
すいません。
スルーしている訳では無く、FSOでMOVEFileを使用した方法を模索していて
Nameを使う方法まで手が付けられていないのが現状です。
この記事を書いている間に、hatenaさんからコードの修正案が出ました。
ちょっと整理しますので時間ください。
(パンチ) 2023/08/07(月) 14:54:27
なぜエラーになるかは、
For Each File In FSO.getfolder(folderPath).Files
のFileはファイルオブジェクト、 それを文字列として扱おうとすると(InStrとかLeftの引数にするなど)、 既定のプロパティのPathが使われて、File.Pathと解釈されてフルパスが返る。
C:\Users\Tommy_\Downloads\無題-2 〜test〜 CaseNo_123456.txt
というように。 すると、
FSO.MoveFile folderPath & File, folderPath & newName
は、
FSO.MoveFile "C:\Users\Tommy_\Downloads\" & "C:\Users\Tommy_\Downloads\無題-2 〜test〜 CaseNo_123456.txt", folderPath & newName
ということになり、 "C:\Users\Tommy_\Downloads\C:\Users\Tommy_\Downloads\無題-2 〜test〜 CaseNo_123456.txt" というファイルは存在しないのでエラーになる。
File.Name とすればファイル名のみ 無題-2 〜test〜 CaseNo_123456.txt が返るのでエラーなく処理できる。
(hatena) 2023/08/07(月) 15:02:31
2023/08/07(月) 14:50:29 の投稿の訂正
誤) 下記に変更すればエラーはなくなると思う。 ' 特定文字列が含まれる場合にファイル名を変更 If InStr(File.Name, targetString) > 0 Then newName = Left(File,Name, InStr(File,Name, targetString) - 1) newName = newName & ".ts" FSO.MoveFile folderPath & File, folderPath & newName End If
正) 下記に変更すればエラーはなくなると思う。 ' 特定文字列が含まれる場合にファイル名を変更 If InStr(File.Name, targetString) > 0 Then newName = Left(File,Name, InStr(File,Name, targetString) - 1) newName = newName & ".ts" FSO.MoveFile folderPath & File.Name, folderPath & newName End If
(hatena) 2023/08/07(月) 15:13:12
横からすみません 波ダッシュと全角チルダの問題は知りませんでした そもそも自分の環境では波ダッシュ入力できなかったです。 (ATOKさんは、波ダッシュだよといってるけど、入力結果は全角チルダ) 他のUnicode文字はそのままでよくても、これだけは変換しておいた方がいいのかも知れませんね
Sub sample() Dim folderPath As String, f As Object, newName As String folderPath = "C:\ほげ\" With CreateObject("Scripting.FileSystemObject") For Each f In .GetFolder(folderPath).Files newName = Split(.GetBaseName(f), " CaseNo")(0) & ".ts" ' CaseNo 以降を削除して拡張子を .ts newName = Replace(newName, ChrW(&H301C), "〜") ' Macで入力された波ダッシュを全角チルダに変換 不要なら行削除 If f.Name <> newName Then f.Name = newName End If Next End With End Sub (´・ω・`) 2023/08/07(月) 15:37:53
newName = Left(File,Name, InStr(File,Name, targetString) - 1)
ですが、カンマ(,)ではなくドット/ピリオド(.)で
newName = Left(File.Name, InStr(File.Name, targetString) - 1)
だと15:02:31の書き込みで判りました。
コードを修正しましたが、アドバイス内容のように上手く処理できません。
(無題-2 〜test〜 CaseNo_123456.txtが返ってきません。)
その後、15:13:12の以下の訂正がありました。
FSO.MoveFile folderPath & File.Name, folderPath & newName
訂正後も見た目のローカルウインドウ上の表示は、
File.Name ---> 無題-2 ?test? CaseNo_123456.txt
newName ---> 無題-2 ?test?.txt
どちらも?が表示されますが、MoveFileは上手く処理できました。
ずっと、ローカルウインドウ上で?が表示されるから変名できないと思っていましたが
?が表示されてもFSOを利用すると変名できる事が理解できました。
これでやっと解決が見えてきました。
アドバイスと修正コードありがとうございます。
’------------------------------------
´・ω・`さんのアドバイスですが、
&H301C −−→ 12316
これは、MACを想定した回答でWindowsの回答では無いのですか?
hatenaさんの修正コードで12316を含んだファイル名でも変名できるようになりましたが
「これだけは変換しておいた方がいいのかも知れませんね」と言う事ですが
理解が追いついていません。
hatenaさんのコードに更コードを付加した方が良いとの事でしょうか ?
(パンチ) 2023/08/07(月) 16:06:32
あ、混乱させたのなら済みません 気にしないでください (´・ω・`) 2023/08/07(月) 16:21:54
あっ、まだ、間違えてました(汗)
> ずっと、ローカルウインドウ上で?が表示されるから変名できないと思っていましたが
> ?が表示されてもFSOを利用すると変名できる事が理解できました。
VBAはある時点で進化が止まっており(MSに見捨てられた?)、
VBE(VBエディター)ではテキストは Shift-JISで処理されており、Unicodeにしかない文字(以後Unicode文字と表記)は?と表示されます。
ですので、Unicode文字の確認はVBEではできないです。
ただし、変数やほとんどの関数やステートメントはUnicodeで処理しているので、Unicode文字も問題なく処理できます。
ワークシートもUnicodeで処理しいるので、Unicode文字を確認する場合はセルに出力するといいでしょう。
VBE上でUnicode文字を記述したい場合は、コードを調べて、ChrW(12316) というようにChrW関数を使います。
ほとんどの関数やメソッドといいましたが、Unicodeに対応していない関数やメソッドもあります。
今回の問題になったDir関数、Nameステートメントがそれにあたります。他にもあります。
Killステートメントとか、、、、
ファイル操作に関しては、FSOはUnicode対応ですので、FSOを使えば問題なく処理できます。
波ダッシュと全角チルダ問題に関しては、見た目では区別がつきにくいので、
いろいろトラブルの元になりかねないので、可能なら、
運用上、どちらか一方に統一するように徹底しておいた方がいいでしょう、という話です。
すでに存在しているファイルに関しては、
何かの機会に一気にどちらかにリネームしておくといいように思います。
(hatena) 2023/08/07(月) 17:08:33
ありがとうございます。
hatenaさん、
?が表示される理由を詳細に説明頂き納得しました。
以下も運用上覚えてくべき事項ですね。
「VBE上でUnicode文字を記述したい場合は、コードを調べて、ChrW(12316) というようにChrW関数を使います。」
お世話になりました。
ありがとうございます。
(パンチ) 2023/08/08(火) 05:42:29
(1) Windowsには、OSの仕様上ファイル名として使えない文字がある \/:*?"<>| の9文字
(2) Excelには、ブック名として使えない文字がある [] の2文字 ・Excelで新規保存、名前を付けて保存する場合、この2文字は使えない ・VBAでSave,SaveAs等でこの2文字をファイル名に使うと実行時エラー ・Explore等で名前を変更すれば、ブック名にこの2文字を使うことはできる ・この2文字を使うとブックを跨いだ参照式で不都合がある
(3) Excel VBAはUnicode文字への対応が完全ではない ・VBAはある時点で進化が止まっており(MSに見捨てられた?)、 VBE(VBエディター)ではテキストは Shift-JISで処理されており、 Unicodeにしかない文字(以後Unicode文字と表記)は?と表示されるので、Unicode文字の確認はVBEではできない。 (ローカルウインドウ、ウォッチウインドウ、イミディエイトウインドウなど) ・変数やほとんどの関数やステートメントはUnicodeで処理しているので、Unicode文字も問題なく処理できる。 ・ワークシートもUnicodeで処理しているので、Unicode文字を確認する場合はセルに出力するとよい ・VBE上でUnicode文字を記述したい場合は、コードを調べて、ChrW(12316) というようにChrW関数を使う ・Unicodeに対応していない関数やメソッドもある。 (Dir関数、Nameステートメント、Killステートメント等) ・「Dir関数」はEXCELにVBAが搭載されたEXCEL95時代からある関数で、レガシーな関数です。 Shift_JISで扱えない文字は 「?」U+003Fに置き換えられる仕様。 可逆性はないので、一旦「?」に置き換わると、元に戻せない
(4) まとると ・ファイル名にUnicode文字を含むファイルの処理には、 VBAのDir関数、Nameステートメント等を使わずにFileSystemObjectを使う必要がある (ExcelVBAでのファイル処理で知っておくべきこと) 2023/08/08(火) 09:26:28
Dir関数はめちゃくちゃ高速に動作しますからねぇ。(FileSystemObjectに比べて、の話) 特にネットワーク越しのディレクトリを相手に100個単位のファイル名を列挙したい時なんかは 実際に体感出来る程の速度差が出ます。
なので文字化けを心配する必要がない事が明らかなのであれば、やっぱDir関数を使いたい所です。
※ ※ ※
ここまで来たら「ついでのついで」で... ^^;
当掲示板でも普通に「絵文字」を使って投稿される質問をちょいちょい見掛けますし、 ChrWやAscWでは素直に対応しきれない文字が至る所で(英語圏に於いてすら)日常的に使われる時代ですので ↓こういうモノの存在も一応知っておいた方がイイと思います。
VBA 文字コードを変換や判定、文字化けを解消する
https://www.tipsfound.com/vba/04012-vba
例えば https://ja.wikipedia.org/wiki/%E5%90%89%E9%87%8E%E5%AE%B6 の「吉」なんかも[0x20BB7]でChrWでは使えないサロゲートペア文字です。
まあ、UNICHAR関数やらUNICODE関数が使えるならあんまり気にしないでも良い事なのかも知れませんけど、 やろうと思えば、ぶっちゃけ↓この様に四則演算と大小比較だけでもカバー出来ちゃうんスよね。
Function szChrW(CharCode) As String Dim b() As Byte If CharCode >= &H10000 Then Dim h As Long, l As Long ReDim b(0 To 3) As Byte h = (CharCode - &H10000) \ &H400& + &HD800& l = (CharCode - &H10000) Mod &H400& + &HDC00& b(1) = h \ &H100&: b(0) = h Mod &H100& b(3) = l \ &H100&: b(2) = l Mod &H100& Else ReDim b(0 To 1) As Byte b(1) = CharCode \ &H100&: b(0) = CharCode Mod &H100& End If szChrW = b End Function
Function szAscW(Chara As String) As Long Dim b() As Byte b = Chara If UBound(b) >= 3 Then If b(1) >= &HD8& And b(1) <= &HDB& And b(3) >= &HDC& And b(3) <= &HDF& Then szAscW = ((b(1) * &H100& + b(0)) - &HD800&) * &H400& + ((b(3) * &H100& + b(2)) - &HDC00&) + &H10000 Else szAscW = b(1) * &H100& + b(0) End If Else szAscW = b(1) * &H100& + b(0) End If End Function
何かの足しになれば... お邪魔しました(その2) ^^;
(白茶) 2023/08/08(火) 09:48:28
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.