Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/25.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/10.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删除Excel中的零长度字符串?_Excel_Vba_Replace_Nonblank - Fatal编程技术网

如何使用VBA删除Excel中的零长度字符串?

如何使用VBA删除Excel中的零长度字符串?,excel,vba,replace,nonblank,Excel,Vba,Replace,Nonblank,我已经在VBA for Excel中创建了一个工具,它可以根据许多标准分析我们收到的.xlsx文件。其中之一是数据集中的空单元格数。但不幸的是,我注意到,我们收到的许多文件中都包含长度为零的单元格,这些单元格被“错误地”算作非空单元格 如果我能够从文件中删除这些内容,这实际上对整个过程非常有益 我在谷歌上搜索了很多这个问题,但到目前为止,我能找到的唯一解决方案是遍历工作表中的所有单元格(我还尝试了常量,还使用find查找所有ZL)。这不是很有效,因为工作表中有大量数据编辑:我也尝试过UsedRa

我已经在VBA for Excel中创建了一个工具,它可以根据许多标准分析我们收到的.xlsx文件。其中之一是数据集中的空单元格数。但不幸的是,我注意到,我们收到的许多文件中都包含长度为零的单元格,这些单元格被“错误地”算作非空单元格

如果我能够从文件中删除这些内容,这实际上对整个过程非常有益

我在谷歌上搜索了很多这个问题,但到目前为止,我能找到的唯一解决方案是遍历工作表中的所有单元格(我还尝试了常量,还使用find查找所有ZL)。这不是很有效,因为工作表中有大量数据编辑:我也尝试过UsedRange.values=UsedRange.values方法,但这会删除前导零,这是我所需要的。

我还发现这是有效的(@-是一个随机字符串,在我的数据中不太可能是单个单元格,如果存在,可以删除):

但如果我只使用单一替换,它不会:

ws.UsedRange.Replace what:=vbNullString, replacement:="", _
                            lookat:=xlWhole, MatchCase:=False
第一个是可以的,但有一些问题:

  • 它需要两倍于一次更换的时间
  • 它是否崩溃或继续工作并不总是很清楚
  • 如果它真的崩溃了,我会留下一些单元格,其中包含-@-,这并不总是很明显的,而且该工具应该可以被那些不能理解VBA的人使用
  • 所以我的问题是:

  • 有没有一种方法可以只用一次更换?为什么替换使用双替换而不是单替换
  • 如果第一个不可能,那么如果代码崩溃,有没有办法“回滚”替换
  • 是否有一种方法可以更新状态栏,以显示替换的执行距离,从而证明代码正在运行(与在Excel中运行替换非常相似)
  • 还是有更好的方法来完成这一切
  • 提前谢谢

    编辑:不幸的是,由于正在处理数据,我需要保留格式,包括前导零

    编辑:下面是我正在查看的数据类型的示例。我想替换长度为零的字符串(这些字符串是没有值的非空白单元格),使其成为真正的空白单元格。


    您可以在单元格中使用返回空字符串的公式,也可以在单元格中使用空字符串常量。要清除第二类单元格,请执行以下操作:

    Sub KillNullConstants()
        Dim cell As Range, Konstants As Range, rng As Range
        Set Konstants = ActiveSheet.UsedRange.Cells.SpecialCells(xlCellTypeConstants)
        Set rng = Nothing
        For Each cell In Konstants
            If Len(cell) = 0 Then
                If rng Is Nothing Then
                    Set rng = cell
                Else
                    Set rng = Union(rng, cell)
                End If
            End If
        Next cell
    
        If Not rng Is Nothing Then
            rng.ClearContents
        End If
    End Sub
    

    要清除返回空字符串的公式单元格,只需更改
    SpecialCells
    代码行。

    我知道这也是一个循环,但可能是一种更快的方法:

    之前:

    对示例数据运行以下代码:

    之后:


    将工作表读入ADO记录集,然后将记录集复制到新工作表似乎可以解决此问题。请尝试以下VBA代码:

    Sub copy_data()
    
    Dim cn As Object
    Set cn = CreateObject("ADODB.Connection")
    
    With cn
        .Provider = "Microsoft.ACE.OLEDB.12.0"
        .ConnectionString = "Data Source=" & ThisWorkbook.FullName & ";" & _
            "Extended Properties=""Excel 12.0 Macro;IMEX=1;HDR=YES"";"
        .Open
    End With
    
    Dim rs As Object
    Set rs = CreateObject("ADODB.Recordset")
    
    rs.Open "SELECT * FROM [Sheet1$];", cn
    
    Dim i As Integer
    Dim fld As Object
    
    With ThisWorkbook.Worksheets("Sheet2")
        .UsedRange.ClearContents
    
        i = 0
        For Each fld In rs.Fields
            i = i + 1
            .Cells(1, i).Value = fld.Name
        Next fld
    
        .Cells(2, 1).CopyFromRecordset rs
        .UsedRange.Columns.AutoFit
    End With
    
    rs.Close
    cn.Close
    
    End Sub
    
    注:

    • 更改代码中的图纸名称,使其与所输入的图纸名称相匹配 使用。您必须在中使用的工作表名称后添加一个
      $
      符号
      rs.Open
      。如果您的工作表被称为“数据”,那么您将
      rs.Open“从[数据$]中选择*”,cn
    • 在连接字符串扩展属性中,
      HDR=YES
      用于指定数据已被删除 标题。ADO可能会更改某些列名,如果它们包含 某些字符-主要是
      字符,通常 替换为
      #
      字符
    潜在问题:

    • 您的数据需要大致采用表格格式,即列名 在第1行中,每个列名下面都有数据值
    • 数据中的任何公式都将转换为值
    • 单元格格式将不会被复制,而是复制数字 格式化为文本将保留为 文本,以便保留前导零
    • 任何长度超过255个字符的单元格值文本都可能被截断 到255个字符(如果需要,可以解决此问题)

    根据您的数据,使用ADO可能会产生比它解决的问题更多的问题

    如何计算包含零长度字符串的单元格的数量,并将该数量添加到空单元格的数量中?我们可以看到这些零长度值但非空值的数据示例吗?谢谢@Luuklag,但我希望能够移除它们,因为我们意识到它们实际上可能会在以后的过程中引发问题。我也没有能够准确地找到一种方法来做到这一点,而不通过所有的细胞循环@不幸的是,我不能分享这些文件,因为它们都是机密文件。但是,如果在单元格中沿“
    =”
    行使用某些内容,然后复制并粘贴值,则可以获得相同的效果。基本上,它们“显示”为空白单元格,但不是。空白单元格就是空白单元格。包含
    =“”
    的单元格不是空白单元格,因为它有一个公式,即使公式的结果是空字符串,单元格本身也包含一个公式。单元格中的值可以从常量(键入它们)或公式中获得。对于公式,即使结果是空字符串,单元格也不是空的,因为它包含公式本身。@FoxfireAndBurnsAndBurns这就是我遇到这个问题的原因。它们不是空白单元格,因此它们被视为空白单元格,但就所有意图和目的而言,它们应该是空白单元格。所以我想把它们去掉。它们都包含零长度字符串,而不是空白或空字符串。谢谢!尽管如问题中所述,我以前也遇到过这种情况,但我不想使用循环单元格的方法,因为这对于我所拥有的数据来说效率很低。您可以将搜索范围限制为10000单元格范围或其他范围。一天结束时,您必须查看每个单元格对象的值,您使用的任何工具或启用的选项或w.e最终都会执行此操作。@learnAsWeGo谢谢您的提示。虽然限制在10000人以内
    Dim X As Double
    
    Option Explicit
    
    Sub Test()
    
    Application.ScreenUpdating = False
    Application.Calculation = xlManual
    
    With ActiveWorkbook.Sheets(1).Range("A1:C7")
        For X = 1 To 3
            .AutoFilter Field:=X, Criteria1:=""
            .Columns(X).Offset(1, 0).SpecialCells(xlCellTypeVisible).Clear
        Next X
        .AutoFilter
    End With
    
    Application.Calculation = xlAutomatic
    Application.ScreenUpdating = True
    
    End Sub
    
    Sub copy_data()
    
    Dim cn As Object
    Set cn = CreateObject("ADODB.Connection")
    
    With cn
        .Provider = "Microsoft.ACE.OLEDB.12.0"
        .ConnectionString = "Data Source=" & ThisWorkbook.FullName & ";" & _
            "Extended Properties=""Excel 12.0 Macro;IMEX=1;HDR=YES"";"
        .Open
    End With
    
    Dim rs As Object
    Set rs = CreateObject("ADODB.Recordset")
    
    rs.Open "SELECT * FROM [Sheet1$];", cn
    
    Dim i As Integer
    Dim fld As Object
    
    With ThisWorkbook.Worksheets("Sheet2")
        .UsedRange.ClearContents
    
        i = 0
        For Each fld In rs.Fields
            i = i + 1
            .Cells(1, i).Value = fld.Name
        Next fld
    
        .Cells(2, 1).CopyFromRecordset rs
        .UsedRange.Columns.AutoFit
    End With
    
    rs.Close
    cn.Close
    
    End Sub