非常奇怪的查找/replace行为
我有一个存储在Windows-1251代码页的Firebird数据库,并使用IBExpert进行pipe理。 我必须使用SQL获取一些结算信息,编辑它,然后将其发送到客户端。 我将查询结果导出为.csv(逗号分隔值)格式,然后使用Microsoft Excel 2010将一堆csvs处理成漂亮的xls(带有边框,字体等)。我不知道为什么,但是IBExpert放置了一个奇怪的在几十年(64731而不是64731)之间的数字值中随处可见。 来自VBA的Asc()
方法告诉我这是ASCII代码页中的#160符号。
现在,我所做的最奇怪的观察:如果您手动复制这个符号,并使用Excel的查找/replacefunction从任何地方删除它,一切都OK。 如果你在任何文本编辑器(如旧的记事本)做同样的事情,一切都还好。 但是,当您尝试使用VBA自动更换时,一切都变得非常非常错误。 不pipe你是从csv本身手动复制#160还是使用Chr(160)
生成它,如果你试图删除所有这些,VBA也会删除一半的逗号。 逗号我的意思是一般已知的符号#44,你可以谷歌“ascii”图片,并检查出来。 我必须再次标记,replace影响一半的逗号,但是他们实际上是相同的符号,我再次检查了两次。
你可以在下面find一个csv的链接,所以你可以放心,我不是疯了。
这里是你可以用来重现魔法的代码
Sub test() Worksheets(1).UsedRange.Replace What:=Chr(160), Replacement:="" End Sub
我会非常感谢能澄清这种现象的人,因为我不能相信VBA就是那种越野车,我想我错过了某个地方
更新:伙计们,我非常抱歉。 我很愚蠢,我上传了错误的csv。 这是正确的
我已将CSV导入范围(“A1”)。 这是我发现的:
- $ F $ 2 =
4 708,200
- 该值不被检测为数字 。 这是由于
CHR(160)
存在于第二位( “4
”之后的“空间” )。 - 如果你想把这个值变成
4708200
( 400万… ),像你所做的那样replaceCHR(160)。 这将删除逗号, 因为现在excel将这些值作为数字来检测 。 - 由于您没有提供正确的信息,Excel认为逗号是千位分隔符 。
如果它应该是4708,2
( 四千… ),请在CSV导入期间进行更正:
- 要正确导入CSV,您必须将CHR(160)作为千位分隔符。
- 逗号将作为十进制符号。
- 这样,Excel将在导入期间将数字值
4708,2
解释为4 708,200
。
在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
macros的代码。
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
所以,正如@takl所build议的那样,解决scheme是修改一千个分隔符属性。 它是.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