Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 非常奇怪的查找/替换行为_Vba_Excel_Replace_Find - Fatal编程技术网

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

Vba 非常奇怪的查找/替换行为,vba,excel,replace,find,Vba,Excel,Replace,Find,我有一个Firebird数据库存储在Windows-1251代码页中,并使用IBExpert进行管理。我必须使用SQL获取一些账单信息,编辑它,然后发送给客户。我将查询结果导出为.csv(逗号分隔值)格式,然后使用MicrosoftExcel2010将一堆csv处理成漂亮的xls(带边框、字体等)。我不知道为什么,但是IBExpert在十年之间的数值中到处都放了一个奇怪的符号(64731而不是64731)Asc()方法告诉我它是ASCII代码页中的#160符号。 现在,我所做的最奇怪的观察:如果

我有一个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
    之后的“空格”)
  • 如果您希望该值变为
    4708200
    (400万…),请像您所做的那样替换CHR(160)。这将删除逗号,因为现在excel将这些值检测为数字
  • 由于您没有提供正确的信息,Excel认为逗号是一个分隔符
如果它应该是
4708,2
(四千…),请在CSV导入期间更正它:

  • 要正确导入CSV,必须将CHR(160)作为千位分隔符
  • 逗号将用作小数点符号
  • 这样,Excel将在导入期间将
    4708200
    解释为数值
    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
更新:以下是替换以前的
工作簿的代码。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
。试试我的宏吧,我想它会满足你的要求。我对最大化表示抱歉。我只是为
查询表录制了一个宏。添加
行。请随意删除所有您认为多余的行。我也是极简主义的爱好者。:)我不会从你的答案中去掉勾号,但我必须自己加上,因为