如何在文件名中创建包含特殊字符的文本文件

nix*_*xda 2 vba excel-2003 createfile

演示我的问题

  • 打开一个新的Excel工作簿并将这些符号设置为单元[A1]
  • 在编辑器中的某处插入以下VBA代码(Alt+ F11)
  • 每行执行一行(F8)
Sub test()

    strCRLF = StrConv(vbCrLf, vbUnicode)
    strSpecialchars = StrConv(Cells(1, 1), vbUnicode)
    strFilename = "c:\test.txt"

    Open strFilename For Output As #1
    Print #1, strSpecialchars & strCRLF;
    Close #1

End Sub

您将获得一个包含[A1]中文字符的文本文件.这证明了如果你知道添加的技巧,VBA能够处理unicode字符StrConv(vbCrLf, vbUnicode)

现在尝试相同的strFilename = "C:\" & strSpecialchars & ".txt".您将收到一个错误,您无法使用此文件名创建文件.当然,你不能使用相同的技巧添加一个新行,因为它的文件名.

如何使用VBA在文件名中创建包含特殊字符的文本文件?
是否有解决方法或我做错了什么?

注意

GSe*_*erg 6

从单元格中检索的值已经是Unicode.

StrConv(vbUnicode)给你"双unicode",因为它使用当前的sustem代码页进行了转换.
然后,该Print命令再次使用当前系统代码页将其转换回"单个unicode".不要这样做.您没有保存unicode,而是在当前设置下保存可能仅在您的特定计算机上显示有效的无效内容.

如果要输出Unicode数据(即,避免将输出文本从Unicode自动转换为ANSI的默认VB机制),您有几个选项.

最简单的方法就是在FileSystemObject不尝试创建任何有关unicode转换的内容的情况下使用:

With CreateObject("Scripting.FileSystemObject")
  With .CreateTextFile("C:\" & Cells(1).Value & ".txt", , True)
    .Write Cells(1).Value
    .Close
  End With
End With
Run Code Online (Sandbox Code Playgroud)

请注意控制Unicode的最后一个参数.

如果您不想这样,您可以声明CreateFileWWriteFile运行:

Private Declare Function CreateFileW Lib "kernel32.dll" (ByVal lpFileName As Long, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByRef lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Private Declare Function WriteFile Lib "kernel32.dll" (ByVal hFile As Long, ByRef lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, ByRef lpNumberOfBytesWritten As Long, ByRef lpOverlapped As Any) As Long

Private Const CREATE_ALWAYS As Long = 2
Private Const GENERIC_WRITE As Long = &H40000000
Run Code Online (Sandbox Code Playgroud)
Dim hFile As Long
hFile = CreateFileW(StrPtr("C:\" & Cells(1).Value & ".txt"), GENERIC_WRITE, 0, ByVal 0&, CREATE_ALWAYS, 0, 0)

Dim val As String
val = Cells(1).Value

WriteFile hFile, &HFEFF, 2, 0, ByVal 0&  'Unicode byte order mark (not required, but to please Notepad)
WriteFile hFile, ByVal StrPtr(val), Len(val) * 2, 0, ByVal 0&

CloseHandle hFile
Run Code Online (Sandbox Code Playgroud)

  • @user202729 StrConv 与 vbUnicode/vbFromUnicode 的合法使用是当您使用 vbUnicode 从 ANSI 字节数组转换为 UTF16 字符串,或使用 vbFromUnicode 从 UTF16 字符串转换为 ANSI 字节数组时。将已经存在的字符串传递给 vbUnicode 是垃圾。 (2认同)