Vba 非常奇怪的查找/替换行为
我有一个Firebird数据库存储在Windows-1251代码页中,并使用IBExpert进行管理。我必须使用SQL获取一些账单信息,编辑它,然后发送给客户。我将查询结果导出为.csv(逗号分隔值)格式,然后使用MicrosoftExcel2010将一堆csv处理成漂亮的xls(带边框、字体等)。我不知道为什么,但是IBExpert在十年之间的数值中到处都放了一个奇怪的符号(64731而不是64731)Vba 非常奇怪的查找/替换行为,vba,excel,replace,find,Vba,Excel,Replace,Find,我有一个Firebird数据库存储在Windows-1251代码页中,并使用IBExpert进行管理。我必须使用SQL获取一些账单信息,编辑它,然后发送给客户。我将查询结果导出为.csv(逗号分隔值)格式,然后使用MicrosoftExcel2010将一堆csv处理成漂亮的xls(带边框、字体等)。我不知道为什么,但是IBExpert在十年之间的数值中到处都放了一个奇怪的符号(64731而不是64731)Asc()方法告诉我它是ASCII代码页中的#160符号。 现在,我所做的最奇怪的观察:如果
现在,我所做的最奇怪的观察:如果你手动复制这个符号,并使用Excel的查找/替换功能从任何地方删除它,一切都正常。如果您在任何文本编辑器(例如,好的旧记事本)中执行相同的操作,则一切仍然正常。但是,当您尝试使用VBA自动化替换时,一切都非常非常错误。无论您使用从csv本身手动复制的#160,还是使用
Chr(160)
生成它,如果您尝试删除所有这些,VBA也会删除一半的逗号。我所说的逗号是指众所周知的符号#44,你可以在谷歌上搜索“ascii”图片并查看它。我必须再次标记,替换会影响一半的逗号,但是它们实际上都是相同的符号,我重新检查了两次。您可以在下面查找到csv的链接,这样您就可以放心我没有疯。
这是你可以用来重现魔法的代码
Sub test()
Worksheets(1).UsedRange.Replace What:=Chr(160), Replacement:=""
End Sub
我将非常感谢有人能够澄清这一现象,因为我简直不敢相信VBA是那种小车,我想我错过了什么
更新:各位,非常抱歉。我太笨了,我上传了错误的csv。这是我已经将CSV导入范围(“A1”)的文件。以下是我的发现:
- $F$2=
4708200
- 该值未被检测为数值。这是由于
存在于第二位(CHR(160)
之后的“空格”)4
- 如果您希望该值变为
(400万…),请像您所做的那样替换CHR(160)。这将删除逗号,因为现在excel将这些值检测为数字4708200
- 由于您没有提供正确的信息,Excel认为逗号是一个分隔符
4708,2
(四千…),请在CSV导入期间更正它:
- 要正确导入CSV,必须将CHR(160)作为千位分隔符李>
- 逗号将用作小数点符号
- 这样,Excel将在导入期间将
解释为数值4708200
4708,2
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
更新:以下是替换以前的工作簿的代码。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
因此,正如@takl所建议的,解决方案是修改千位分隔符属性。 如果您使用的是
ActiveSheet.QueryTables.Add
方法,那么它就是.textfile千分位分隔符
,如果您使用的是工作簿.OpenText
方法,那么它就是千分位分隔符。
我真的很感谢他的帮助,但我只需要使用工作簿.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
@p但它没有缩短,带有“Сачаааа”标题的黑色按钮是您的选择。您对逗号的评论向我表明,它是将替换文本从文本转换为数字,然后显示为不带逗号的数字。逗号在某些语言环境中是千位分隔符,在其他语言环境中是十进制分隔符。例如,如果我替换“234567”中的“”,则无论我是否愿意,结果都会被类型转换为234567(按数字格式显示)。要保留类型,您需要使用循环或.Replace或.Replace数字格式以外的其他内容,然后再删除字符检查@Cor\u Blimey所说内容的简单方法是用“
替换,而不是”
@Cor\u Blimey抱歉,老实说,我不明白您的解决方法。请澄清它们或给出一些解释代码。一个循环(内部是什么?)如何代替.Replace工作?用文本替换#160,然后用零替换文本也没用,你是说别的吗?解释,我确实需要它。我下载了你的链接文件。它看起来像一个普通的欧洲CSV,在Excel2010(法语版)中可以很好地打开,除了对我来说不是西里尔文的文本。我想知道你的问题是否是将160错误地理解为Unicode序列的一部分。伙计,我很抱歉我浪费了你的时间来编写所有这些代码-u-我给了你一个错误的文件,请重新检查这个问题,我已经编辑了哇,伙计,非常感谢你为编写解决方案付出的努力!还有一件事需要澄清,这非常重要。当我使用工作簿.OpenText
打开csv时,我必须使用Local:=True
选项,否则在导出过程中所有内容都将被置乱,如何使用QueryTables.Add
方法?如果它能对你有所帮助的话,下面是我在回答的末尾添加了你的eyecandy
宏的新版本。您不需要使用工作簿.OpenText
。试试我的宏吧,我想它会满足你的要求。我对最大化表示抱歉。我只是为查询表录制了一个宏。添加行。请随意删除所有您认为多余的行。我也是极简主义的爱好者。:)我不会从你的答案中去掉勾号,但我必须自己加上,因为