非常奇怪的查找/替换行为

时间:2014-11-18 16:58:03

标签: excel vba excel-vba replace find

我有一个Firebird数据库存储在Windows-1251代码页中并使用IBExpert进行管理。我必须使用SQL获取一些计费信息,编辑它然后将其发送给客户端。我将查询结果导出为.csv(逗号分隔值)格式,然后使用Microsoft Excel 2010将一堆csvs处理成漂亮的xls(带边框,字体等)。我不明白为什么,但IBExpert放置一个奇怪的几十年间数字值中的符号(64 731而不是64731)。来自VBA的Asc()方法告诉我它是ASCII代码页中的#160符号 现在,我做的最奇怪的观察:如果你手动复制这个符号并使用Excel的查找/替换功能从任何地方删除它,一切都OK。如果你在任何文本编辑器中做同样的事情(例如好的旧记事本),一切都还可以。但是当你尝试使用VBA自动替换时,一切都非常非常错误。无论您是使用csv本身手动复制的#160还是使用Chr(160)生成它,如果您尝试删除所有这些,VBA也会删除一半的逗号。用逗号我的意思是通常已知的符号#44,你可以谷歌“ascii”图片并检查出来。我必须再次标记,替换影响 half 逗号,但是它们实际上都是相同的符号,我重新检查了两次。
你可以在下面找到一个csv的链接,这样你就可以放心,因为我并不疯狂。
这是您可以用来重现魔法的代码

Sub test()
    Worksheets(1).UsedRange.Replace What:=Chr(160), Replacement:=""
End Sub

我会非常感谢会澄清这种现象的人,因为我无法相信VBA 错误,我想我错过了某个地方

更新:伙计们,我非常抱歉。我是如此愚蠢,以至于我上传了错误的csv。这是right one

2 个答案:

答案 0 :(得分:1)

我已将CSV导入范围(“A1”)。这是我发现的:

  • $ F $ 2 = 4 708,200
  • 该值未被检测为数字。这是因为CHR(160)存在于第二位( 4 之后的“空格”。)
  • 如果您希望该值变为4708200四百万... ),请替换CHR(160),就像您已经完成的那样。这将删除逗号,因为现在excel会将这些值检测为数字
  • 由于您未提供正确的信息,Excel认为逗号是千位分隔符

如果它应该是4708,2四千...... ),请在CSV导入过程中更正它:

  • 要正确导入CSV,您必须将CHR(160)作为千位分隔符。
  • 逗号将作为小数符号。
  • 这样,Excel会在导入过程中将4 708,200解释为数值4708,2

在VBA中使用REPLACE时,Excel假定逗号是千位分隔符。为什么?很难说。但是,您没有提供它不是。 :)

以下是正确导入文件的代码。

With ActiveSheet.QueryTables.Add(Connection:= _
    "TEXT;H:\testfile2.csv", Destination:=Range("$A$1"))
    .Name = "testfile2.csv"
    .FieldNames = True
    .RowNumbers = False
    .FillAdjacentFormulas = False
    .PreserveFormatting = True
    .RefreshOnFileOpen = False
    .RefreshStyle = xlInsertDeleteCells
    .SavePassword = False
    .SaveData = True
    .AdjustColumnWidth = True
    .RefreshPeriod = 0
    .TextFilePromptOnRefresh = False
    .TextFilePlatform = 1251
    .TextFileStartRow = 1
    .TextFileParseType = xlDelimited
    .TextFileTextQualifier = xlTextQualifierDoubleQuote
    .TextFileConsecutiveDelimiter = False
    .TextFileTabDelimiter = False
    .TextFileSemicolonDelimiter = True
    .TextFileCommaDelimiter = False
    .TextFileSpaceDelimiter = False
    .TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1)
    .TextFileThousandsSeparator = Chr(160) ' Here's that thousands separator!
    .TextFileTrailingMinusNumbers = True
    .Refresh BackgroundQuery:=False
End With

更新:以下是替换以前的Workbooks.OpenText宏的代码。

Sub eyecandy()
Dim SelectedItem
Dim Wb As Workbook, Sh As Worksheet
Dim WbName As String, WbFullName As String

    With Application.FileDialog(msoFileDialogFilePicker)
        .Title = "  "
        .InitialFileName = ThisWorkbook.Path & Application.PathSeparator & "*.csv"
        .AllowMultiSelect = True
        If .Show = False Then Exit Sub

        Application.ScreenUpdating = False
        For Each SelectedItem In .SelectedItems
            Set Wb = Workbooks.Add

            ' Get the file name
            WbFullName = Replace(SelectedItem, ThisWorkbook.Path & Application.PathSeparator, "")
            WbName = Replace(WbFullName, ".csv", "")

            ' Deletes unnecessary sheets
            Do Until Wb.Sheets.Count = 1
                Application.DisplayAlerts = False
                Wb.Sheets(1).Delete
                Application.DisplayAlerts = True
            Loop

            Set Sh = Wb.Sheets(1)

            With Sh.QueryTables.Add(Connection:= _
                "TEXT;" & SelectedItem, Destination:=Sh.Range("$A$1"))
                .Name = WbName
                .FieldNames = True
                .RowNumbers = False
                .FillAdjacentFormulas = False
                .PreserveFormatting = True
                .RefreshOnFileOpen = False
                .RefreshStyle = xlInsertDeleteCells
                .SavePassword = False
                .SaveData = True
                .AdjustColumnWidth = True
                .RefreshPeriod = 0
                .TextFilePromptOnRefresh = False
                .TextFilePlatform = 1251
                .TextFileStartRow = 1
                .TextFileParseType = xlDelimited
                .TextFileTextQualifier = xlTextQualifierDoubleQuote
                .TextFileConsecutiveDelimiter = False
                .TextFileTabDelimiter = False
                .TextFileSemicolonDelimiter = True
                .TextFileCommaDelimiter = False
                .TextFileSpaceDelimiter = False
                .TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1)
                .TextFileThousandsSeparator = Chr(160)
                .TextFileTrailingMinusNumbers = True
                .Refresh BackgroundQuery:=False
            End With
            Sh.Activate
            ActiveWindow.DisplayGridlines = False
            With Sh.UsedRange
                .Borders.LineStyle = xlContinuous
                .Rows(1).Font.Bold = True
                .Rows(1).Borders.Weight = xlThick
            End With
            Sh.Name = WbName
            Wb.SaveAs Filename:=WbName, FileFormat:=56
            Wb.Close SaveChanges:=False
        Next SelectedItem
        Application.ScreenUpdating = True
    End With
End Sub

答案 1 :(得分:0)

因此,正如@takl建议的那样,解决方案是修改千位分隔符属性。 如果您使用的是.TextFileThousandsSeparator方法,则为ActiveSheet.QueryTables.Add;如果您使用的是.ThousandsSeparator方法,则为Workbooks.OpenText。 我非常感谢他的帮助,但我只是 使用Workbooks.OpenText方法,因为它支持Local属性。所以,这是我脚本中编辑过的文件处理循环

'walk through selected files
For Each SelectedItem In .SelectedItems 
    Workbooks.OpenText _
        Filename:=SelectedItem, _
        Origin:=xlWindows, _
        StartRow:=1, _
        DataType:=xlDelimited, _
        TextQualifier:=xlTextQualifierNone, _
        ConsecutiveDelimiter:=False, _
        Semicolon:=True, _
        ThousandsSeparator:=Chr(160), _
        Local:=True