【问题标题】:Is there a way of doing IF +有没有办法做 IF +
【发布时间】:2020-05-01 11:35:17
【问题描述】:

我正在处理一张纸,而我正在做的事情似乎非常缓慢且冗长。我希望有一种更巧妙的方式来做到这一点。

我想做在 Excel 中看起来像这样但在 VBA 中的操作:-if(Search("5,",A10,1)>0,A5,0)+if(Search("4,",A10,1)>0,A4,0)+if(Search("3,",A10,1)>0,A3,0) 等等。

我可以看到在 vba 中执行此操作的唯一方法是搜索将数据添加到其他位置,然后稍后对其进行求和。我有这个:-

    Sub AmorTotal_1()

Dim Coll As String
Dim ClTo As String, RuTo As String, ElTo As String, Jig As String, Teth As String, Admin As String, Crane As String
Dim ClToS As Integer, RuToS As Integer, ElToS As Integer, JigS As Integer, TethS As Integer, AdminS As Integer, CraneS As Integer

Coll = "B"
ClTo = 5
RuTo = 6
ElTo = 7
Jig = 8
Teth = 9
Admin = 10
Crane = 11

ThisWorkbook.Sheets(2).Range(Coll & 2).Value = ThisWorkbook.Sheets(1).Range(Coll & 2).Value

If InStr(1, Range(Coll & 12), "5,") > 0 Then
ThisWorkbook.Sheets(2).Range(Coll & 3).Value = ThisWorkbook.Sheets(1).Range(Coll & ClTo).Value
Else
ThisWorkbook.Sheets(2).Range(Coll & 3).Value = 0
End If

If InStr(1, Range(Coll & 12), "6,") > 0 Then
ThisWorkbook.Sheets(2).Range(Coll & 4).Value = ThisWorkbook.Sheets(1).Range(Coll & RuTo).Value
Else
ThisWorkbook.Sheets(2).Range(Coll & 4).Value = 0
End If

If InStr(1, Range(Coll & 12), "7,") > 0 Then
ThisWorkbook.Sheets(2).Range(Coll & 5).Value = ThisWorkbook.Sheets(1).Range(Coll & ElTo).Value
Else
ThisWorkbook.Sheets(2).Range(Coll & 5).Value = 0
End If

If InStr(1, Range(Coll & 12), "8,") > 0 Then
ThisWorkbook.Sheets(2).Range(Coll & 6).Value = ThisWorkbook.Sheets(1).Range(Coll & Jig).Value
Else
ThisWorkbook.Sheets(2).Range(Coll & 6).Value = 0
End If

If InStr(1, Range(Coll & 12), "9,") > 0 Then
ThisWorkbook.Sheets(2).Range(Coll & 7).Value = ThisWorkbook.Sheets(1).Range(Coll & Teth).Value
Else
ThisWorkbook.Sheets(2).Range(Coll & 7).Value = 0
End If

If InStr(1, Range(Coll & 12), "10,") > 0 Then
ThisWorkbook.Sheets(2).Range(Coll & 8).Value = ThisWorkbook.Sheets(1).Range(Coll & Admin).Value
Else
ThisWorkbook.Sheets(2).Range(Coll & 8).Value = 0
End If

If InStr(1, Range(Coll & 12), "11,") > 0 Then
ThisWorkbook.Sheets(2).Range(Coll & 11).Value = ThisWorkbook.Sheets(1).Range(Coll & Crane).Value
Else
ThisWorkbook.Sheets(2).Range(Coll & 11).Value = 0
End If


ThisWorkbook.Sheets(1).Range(Coll & 13).Value = ThisWorkbook.Sheets(2).Range(Coll & 3).Value + ThisWorkbook.Sheets(2).Range(Coll & 4).Value + ThisWorkbook.Sheets(2).Range(Coll & 5).Value + ThisWorkbook.Sheets(2).Range(Coll & 6).Value + ThisWorkbook.Sheets(2).Range(Coll & 7).Value + ThisWorkbook.Sheets(2).Range(Coll & 8).Value + ThisWorkbook.Sheets(2).Range(Coll & 9).Value

End Sub

我需要跨 20 列和多行执行此操作,因此希望有另一种方法。

我在网上搜索过,但找不到任何我能理解的东西(我还是 VBA 新手)。

以下是一些数据的示例。总之,

用户在第 5-11 行输入了一些工具的一些值。用户可以决定某些工具可以用于其他项目(由列表示的项目),因此他们可能希望在整个这些项目中分摊这些工具的成本。在第 1 项上,用户决定第 8 行和第 9 行(第 12 行)可用于第 1、2、3、5 项(第 15 行)。第 13 行取项目 1 中单元格 B8 和 B9 中的价格值,第 16 行是摊销值,即第 2 行每个参考项目 1、2、3 + 5 的成本。这是由该项目总计完成的成本除以(1、2、3+5 的总项目成本)* 摊销值第 13 行。

希望这是有道理的,但解释起来有点棘手。

【问题讨论】:

  • VBA IIf() 函数等效于 Excel 的 IF(),但可能有比这更优雅的方法。你能分享一些示例数据和预期的输出吗?
  • A10全部内容的范围是多少?
  • 嗨@jsheeran 我将能够在星期一分享示例数据。我已经在我的个人笔记本电脑上手动输入了这个,因为我的工作电脑已经失去了连接到 wifi 的能力并且拒绝手机的热点,这就是我在我的个人笔记本电脑上所做的。道歉:(
  • @RonRosenfeld 好问题,所以在上面的示例中,第 1 到第 9 行包含工具成本。用户可以选择将这些工具与另一个项目摊销(项目 1 是 A 列,依此类推,直到项目 20)。在 A10 中,他们可以选择他们希望摊销的行。所以说A4,A5范围内的工具也用于项目20,用户将4,5放在A10范围内。我希望这是有道理的。
  • 那么,在您提到的情况下,您想要 A4 和 A5 的总和?您更喜欢公式还是 VBA?哪个版本或 Excel。

标签: excel vba


【解决方案1】:

如果我理解正确的话,这里有两个函数可以在 B13 和 B16 中使用

注意:

  • 由于公式中没有直接引用各种成本项目,因此如果更改,公式将不会自动更新。
  • 如果行列表或项目单元格列表发生更改,公式将更新
  • 两种解决方法:
    1. 在每个函数的声明语句后添加Application.Volatile(这可能会减慢工作表的计算速度)。
    2. 将列/行号参数更改为范围引用
Option Explicit

'sRows is the cell (or string) containing the commas separated row numbers
'lItemCol is the column number on which to run this calculation.
'    If omitted, it will default to the column containing the formula

Function toolCostToAmortize(sRows As String, Optional lItemCol As Long = 0) As Currency
    Dim v
    Dim P As Currency

If lItemCol = 0 Then lItemCol = Application.Caller.Column

For Each v In Split(sRows, ",")
    P = P + Cells(v, lItemCol)
Next v

toolCostToAmortize = P
End Function
'======================================
'sItemIDX is the cell containing the comma-separated string to use
'cCostToAmortize is the cell reference containing the toolCostToAmortize result
'lItemRow is optional and is the row containing the list of Items (row 1 in your screenshot)
'    If omitted, it will default to row 1

Function amortizedValue(sItemIDX As String, cCostToAmortize As Currency, Optional lItemRow As Long = 1) As Currency
    Dim v
    Dim P As Currency

For Each v In Split(sItemIDX, ",")
    'Assuming Item List starts in column B
    ' But could use other methods to locate table
    P = P + Cells(lItemRow + 1, v + 1)
Next v

amortizedValue = cCostToAmortize / P * Cells(lItemRow + 1, Application.Caller.Column)

End Function

他们提供了您屏幕截图中显示的答案。

【讨论】:

  • 嗨罗恩,我在运行时遇到错误,我只是将它复制并粘贴到表 1 vba 中。错误是run-time error '1004': Application-defined or object-defined error任何想法,再次感谢您的帮助。 :-)
  • 嗨,Ron,我可以厚颜无耻地请求你在上面写更多的注释,这样我就可以了解它在做什么?因为我是新手,所以有些部分我不明白。谢谢。
  • @StevenByrne 我添加了一些解释函数参数的 cmets。可能你没有正确设置它们。使用您的数据,我没有看到该错误。我还添加了有关可能问题的注释。建议您检查所使用的各种 VBA 函数的 HELP,并检查 Locals 窗口中的变量,在 UDF 运行时逐步执行它。然后询问您是否有具体问题。
  • @StevenByrne 我只是简单地将其复制并粘贴到 sheet 1 vba 中。 它需要在 常规模块中,而不是在床单后面。
  • 您好罗恩,感谢您的帮助。我现在让toolCostToAmortize 工作,但不能让另一个工作。感谢您对此的帮助。抱歉,我对此非常非常陌生。所以我的第一个错误是,我把它放错了地方,其次我不知道一个函数在单元格中创建了一个新公式。我也不知道如何检查Locals 窗口中的变量。真的很感谢您的指导:)所以为了让最后一点工作,这显然是我做错了什么,我把=amortizedValue(B15)放在单元格B16中,这是正确的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-10
  • 1970-01-01
  • 1970-01-01
  • 2021-04-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多