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

时间:2013-01-10 15:42:47

标签: 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]中文字符的文本文件。这证明了如果您知道添加StrConv(vbCrLf, vbUnicode)

的技巧,VBA就能够处理unicode字符

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

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

注意

2 个答案:

答案 0 :(得分:5)

从单元格中检索的值已经是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

请注意控制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
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

答案 1 :(得分:3)

您使用FileSystemObject处于正确的轨道上。正如Morbo提到的,你可以延迟绑定这个,所以没有设置参考。 FSO有一个CreateTextFile函数,可以在unicode中设置,因此字符将显示为“??????”在VBA中,但会正确写入文件名。请注意,CreateTextFile函数的第二个参数指定文件名的unicode字符串。以下将为您解决问题:

Sub test()
    Dim strCRLF As String, strSpecialchars As String, strFilename As String
    Dim oFSO As Object, oFile As Object

    strCRLF = StrConv(vbCrLf, vbUnicode)
    strSpecialchars = StrConv(Cells(1, 1), vbUnicode)
    strFilename = "C:\" & Cells(1, 1).Value & ".txt"

    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Set oFile = oFSO.CreateTextFile(strFilename, , True)

    oFile.Write strSpecialchars & strCRLF

    oFile.Close

    Set oFile = Nothing
    Set oFSO = Nothing
End Sub