【问题标题】:Search and replace by column header按列标题搜索和替换
【发布时间】:2021-05-25 12:01:07
【问题描述】:

抱歉……我的 VBA 技能几乎不存在……

我要做的是在 Excel 中创建一个宏,其中列 (1) 中的数据被列标题(SAND、LS 和 CS)替换。这是一个示例表:

DEPTH SAND LS CS
600 1 -999 -999
700 -999 -999 1
800 1 -999 -999
900 -999 1 -999

这是我运行宏时的结果:

DEPTH SAND LS CS
600 SAND -999 -999
700 -999 -999 CS
800 SAND -999 -999
900 -999 LS -999

但是,我需要让 Excel 读取第一行中的 Header 来替换 1。不是列字母(例如读取 SAND 而不是 Columns("B:B") 在下面的代码中。我有许多相同格式的不同文件,但列数和列标题不同,因此问题。

这是我创建的宏的示例。

Sub LithReplace()
'
' LithReplace Macro
'

'
    Range("B1").Select
    Selection.Copy
    Columns("B:B").Select
    Selection.Replace What:="1", Replacement:="SAND            ", LookAt:= _
        xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
        ReplaceFormat:=False, FormulaVersion:=xlReplaceFormula2
    Range("C1").Select
    Application.CutCopyMode = False
    Selection.Copy
    Columns("C:C").Select
    Selection.Replace What:="1", Replacement:="LS              ", LookAt:= _
        xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
        ReplaceFormat:=False, FormulaVersion:=xlReplaceFormula2
    Range("D1").Select
    Application.CutCopyMode = False
    Selection.Copy
    Columns("D:D").Select
    Selection.Replace What:="1", Replacement:="CS               ", LookAt:= _
        xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
        ReplaceFormat:=False, FormulaVersion:=xlReplaceFormula2
End Sub

提前致谢。

【问题讨论】:

  • 阅读How to avoid using Select in Excel VBA可能会让您受益。
  • 请查看我在下面写的答案。该链接只是一个说明,让您了解如何编写更好的代码。请不要在 cmets 中发布代码。它变得无用,因为您无法正确格式化它。
  • 谢谢!这非常有效。我将添加更多代码来完成工作流程。

标签: excel vba replace


【解决方案1】:

试试:

Sub test()
Dim rng As Range
Dim MyColumn As Range
Set rng = Range("A1").CurrentRegion 'dataset. Replace A1 by top left cell reference

For Each MyColumn In rng.Columns
    If MyColumn.Column > 1 Then 'we skip first column
        MyColumn.Replace "1", MyColumn.Cells(1, 1).Value, xlPart 'replace 1 with 'top cell of each column
    End If
Next MyColumn

Set rng = Nothing
End Sub

代码将遍历每一列,并将任何1 替换为每一列的顶部单元格值,因此它适用于任何列数量

我在执行代码后得到这个:

重要提示:考虑使用xlWhole而不是xlPart,因为现在如果有任何1,它将被替换,所以像213这样的东西可以转换成@987654330 @。

Range.Replace method (Excel)

【讨论】:

  • 大声笑,我们用几乎相同的例子为xlWhole写了相同的答案^^
  • @Pᴇʜ 是的,我正在阅读您的答案并认为同样的哈哈。我想我们俩都对Range.Replace 有过信任问题,我们永远不会忘记,哈哈
  • 仅供参考,您可能对使用单行评估的替代方法感兴趣:-)
  • @T.M.我猜你的意思是 If...End IF 我使用通用语法让 OP 更容易理解,因为 OP 说 我的 VBA 技能几乎不存在。但实际上,它可能是像If MyColumn.Column > 1 Then MyColumn.Replace "1", MyColumn.Cells(1, 1).Value, xlPart 这样的单行。感谢您指出这一点!
  • @FoxfireAndBurnsAndBurns 语法完全没问题(+1);只是想使用基于预定义公式字符串的一个衬里来引起您对我自己(迟到的)回复的注意:rng.Value = Evaluate(myFormula)
【解决方案2】:

执行如下通用的操作:

  1. 定义您的工作表
  2. 找出有多少列
  3. 定义需要进行替换的范围。在这里,我们希望从第 2 列转到最后一列,并保留第一列。
  4. 循环列以将每列中的 1 替换为其标题。

举例

Option Explicit

Public Sub LithReplace()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("Sheet1") 'specify your sheet name
    
    Dim LastUsedColumn As Long 'find the last used column in the header row
    LastUsedColumn = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
    
    Dim RangeToReplace As Range 'range to replace is from column 2 to the last used column
    Set RangeToReplace = ws.Range(ws.Columns(2), ws.Columns(LastUsedColumn))
    
    Dim Column As Range
    For Each Column In RangeToReplace.Columns 'loop through all columns in that range
        'in each column replace "1" with the value in the header cell of that column Column.Cells(1, 1)
        Column.Replace What:="1", Replacement:=Column.Cells(1, 1), _
                       LookAt:=xlWhole, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
                       ReplaceFormat:=False
        
    Next Column
End Sub

请注意,您需要LookAt:=xlWhole,否则如果您LookAt:=xlPart 并且有一个数字包含 1,例如614,它将替换为6SAND4

【讨论】:

  • 仅供参考,您可能对使用单行评估的替代方法感兴趣@PEH :-)
  • @T.M.不错的替代方法。会很有趣,这是一个优于另一个的优势,例如。哪个更快。
  • 值得一试;可能取决于迭代中要替换的列数以及您正在处理整个列的事实@PEH
  • @T.M.替换整列与仅替换具有数据的行不会改变任何内容。 Excel 足够聪明,可以在最后省略空行。
【解决方案3】:

通过Evaluate()替代

基本上是一个班轮:rng.Value = Evaluate(myFormula)

Sub ReplaceNumberOne()
    'a) define data range
    With Sheet1                  ' << change to wanted project's sheet Code(Name)
        Dim LastRow As Long, LastCol As Long
        LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
        LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
    
        Dim rng As Range
        Set rng = .Range("A1", .Columns(LastCol)).Resize(LastRow)
        
    End With
    'b) define range addresses (strings)
    Dim dataAddr As String, headAddr As String
    dataAddr = rng.Address: headAddr = rng.Resize(1, LastRow).Address
    'c) define formula to be evaluated
    Dim myFormula As String          ' e.g. "=if(A1:D5=1,A1:D1,A1:D5&"""")"
    myFormula = Replace(Replace("=if(x=1,y,x&"""")", "x", dataAddr), "y", headAddr)
    Debug.Print myFormula
    '~~~~~~~~~~~~~~~~~~~~~~~~
    'd) replace by one code line
    '~~~~~~~~~~~~~~~~~~~~~~~~
    rng.Value = Evaluate(myFormula)
End Sub

【讨论】:

    猜你喜欢
    • 2020-07-03
    • 2020-07-20
    • 1970-01-01
    • 2011-03-19
    • 2010-11-19
    • 2011-11-09
    • 1970-01-01
    • 2021-05-02
    相关资源
    最近更新 更多