【问题标题】:Multiplying two columns based on header name根据标题名称将两列相乘
【发布时间】:2019-03-07 16:06:27
【问题描述】:

我正在尝试根据标题名称将两列相乘(每次都可以更改位置 - 因此固定的单元格范围不起作用)。

到目前为止,我得到了以下一块

Dim ws As Worksheet
Dim lrow As Long
Dim Amount, Bill, USD As Range
Dim Rngheaders As Range

Set ws = ThisWorkbook.Sheets("CSV Data PR")
Set Rngheaders = ws.Range("1:1")
lrow = ws.Cells(Rows.Count, 1).End(xlUp).Row - 1

Set Amount = ws.Rows(1).Find(What:="Amount")
Set Bill = ws.Rows(1).Find(What:="Bill.qty")
Set USD = ws.Rows(1).Find(What:="In USD")

ws.Range(USD.Address).Offset(1, 0).Resize(lrow) = Range(Amount.Address).Offset(1, 0) * Range(Bill.Address).Offset(1, 0)

这可行,除了它只计算第 2 行(我需要它逐行计算)。

所需的输出应该类似于:

【问题讨论】:

    标签: excel vba


    【解决方案1】:

    您需要添加一个循环来循环遍历每一行。您通过找到最后一行完成了部分工作。您还设置了第一行为Rngheaders,但没有使用。

    Dim ws As Worksheet
    Dim lrow As Long
    Dim AmountCol as Long
    Dim BillCol as Long
    Dim USDCol as Long
    Dim Rngheaders As Range
    Dim x as long
    
    Set ws = ThisWorkbook.Sheets("CSV Data PR")
    Set Rngheaders = ws.Range("1:1")
    lrow = ws.Cells(Rows.Count, 1).End(xlUp).Row
    
    AmountCol = Rngheaders.Find(What:="Amount").Column
    BillCol = Rngheaders.Find(What:="Bill.qty").Column
    USDCol = Rngheaders.Find(What:="In USD").Column
    
    For x= 2 to lrow
         ws.Cells(x,USDCol) = ws.Cells(x, AmountCol) * ws.Cells(x, BillCol)
    Next x
    

    【讨论】:

    • 我不需要这个,但我会保存这段代码,以防万一。我喜欢它,简单、整洁、准确。不喜欢调用函数之类的其他答案。
    • 非常感谢!正是我要找的东西,而且确实 - 不知道为什么我不使用标题参考行。
    【解决方案2】:

    请考虑为您的目的使用用户定义函数。将函数的代码粘贴到标准代码模块中。

    Function BillTotal(R As Long) As Double
        ' 07 Mar 2019
        ' returns -1 in case of error
    
        Dim Amt As Long
        Dim Qty As Long
    
        Application.Volatile
        On Error Resume Next
        Amt = Application.WorksheetFunction.Match("amount", Rows(1), 0)
        If Err.Number = 0 Then
            Qty = Application.WorksheetFunction.Match("bill.qty", Rows(1), 0)
        End If
        If Err Then
            BillTotal = -1
        Else
            BillTotal = Val(Cells(R, Amt).Value) * Val(Cells(R, Qty).Value)
        End If
    End Function
    

    在你希望得到结果的单元格中写下这样的函数调用。

    =BillTotal(Row())
    

    作为替代方案,您可以使用相同的功能来实现您的原始想法。只需在 For ... Next 循环中调用它并将结果写入由 R 和 C 定义的单元格,其中行号 R 由循环提供,C 可以从 MATCH 函数中获得,如我的函数所示。如果这样使用,就不需要Application.Volatile这行了。

    【讨论】:

      【解决方案3】:

      试试这个代码:

      Dim ws As Worksheet
      Dim lrow As Long
      Dim Amount As Range
      Dim Bill As Range
      Dim USD As Range
      Dim Rngheaders As Range
      Dim counter As Integer
      
      Set ws = ThisWorkbook.Sheets("CSV Data PR")
      Set Rngheaders = ws.Range("1:1")
      lrow = ws.Cells(Rows.count, 1).End(xlUp).Row - 1
      
      Set Amount = ws.Rows(1).Find(What:="Amount")
      Set Bill = ws.Rows(1).Find(What:="Bill.qty")
      Set USD = ws.Rows(1).Find(What:="In USD")
      
      
      For counter = 1 To lrow
          USD.Offset(counter, 0).Value = Amount.Offset(counter, 0).Value * Bill.Offset(counter, 0).Value
      Next counter
      

      我设置了金额、账单和美元范围的变量类型

      由于这些已经是范围,您可以直接引用它们。不用Range(USD.Address)

      另外,你没有使用这一行:Set Rngheaders = ws.Range("1:1")

      试一试,让我知道它是否有效。我无法测试它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-27
        • 2021-05-07
        • 1970-01-01
        • 2021-06-18
        相关资源
        最近更新 更多