简体   繁体   English

如何从VBA设置公式以分配单元格值?

[英]How to set a formula from VBA to assign cell value?

I am setting a cell value in Sheet1 with a formula that involves cells from Sheet1 and Sheet2. 我使用涉及Sheet1和Sheet2中单元格的公式在Sheet1中设置单元格值。 Is there a way to set such formula from VBA? 有没有办法从VBA设置这样的公式?

Here is what I have: 这是我所拥有的:

I fill some information from B11 to M11 all over to row number 29, like filling a form per rows. 我从B11到M11一直填充一些信息,直到第29行,就像每行填写一个表格一样。 Some times it will be only one row with information and it could also be all of the tables with data. 有时,只有一行包含信息,也可能是所有带有数据的表。

In column G, I have a dropdown and according to the value from this dropdown, the respective H cell is filled. 在G列中,我有一个下拉列表,并根据该下拉列表中的值填充相应的H单元格。

I manage to set the formula for that, but due to security, I want to set it from VBA. 我设法为此设置了公式,但是出于安全性考虑,我想从VBA进行设置。

=IFERROR(VLOOKUP(G11;Data!B2:D13;3;FALSE);0)

WorksheetFunction.Vlookup() works quite nicely, if you use correctly the Ranges and the parameters: 如果您正确使用Ranges和参数, WorksheetFunction.Vlookup()很好地WorksheetFunction.Vlookup()

Public Function SomeFormula() As Variant

    On Error GoTo SomeFormula_Error

    Dim result As Variant
    result = WorksheetFunction.VLookup(Range("G11"), Worksheets("Data").Range("B2:D13"), 3, False)
    SomeFormula = result

    On Error GoTo 0
    Exit Function

SomeFormula_Error:

    SomeFormula = 0

End Function

You could just keep your formula in G column and protect that range so user can't edit it. 您可以只将公式保留在G列中并保护该范围,以便用户无法对其进行编辑。

Alternatively, using the Worksheet_Change event handler: 或者,使用Worksheet_Change事件处理程序:

Private Sub Worksheet_Change(ByVal Target As Range)
Dim cl As Range
Dim val as Variant
' In case the change is NOT in column G, then Exit.
If Intersect(Target, Columns("G")) Is Nothing Then Exit Sub
For Each cl in Intersect(Target, Columns("G"))
    val = Application.Vlookup(cl.Value, ThisWorkbook.Worksheets("Data").Range("B2:D13"), 3, False)
    If IsError(val) Then
        cl.Offset(0, 1).Value = 0
    Else
        cl.offset(0, 1).Value = val
    End If
Next
End Sub

If you need to do the same sort of thing against multiple columns, it's a little trickier because you can only have one Worksheet_Change handler in a given sheet. 如果您需要对多个列执行相同的操作,则将有些棘手,因为给定Worksheet_Change只能有一个Worksheet_Change处理程序。 So you'll need to modify it like below. 因此,您需要像下面那样对其进行修改。 This could use to be streamlined a bit to reduce some redundancy, but that's an exercise for another Question :) 可以稍微简化一下以减少一些冗余,但这是另一个问题的练习:)

Private Sub Worksheet_Change(ByVal Target As Range)
Dim cl As Range
Dim val as Variant
' Handles column G
If Not Intersect(Target, Columns("G")) Is Nothing Then 

    For Each cl in Intersect(Target, Columns("G"))
        val = Application.Vlookup(cl.Value, ThisWorkbook.Worksheets("Data").Range("B2:D13"), 3, False)
        If IsError(val) Then
            cl.Offset(0, 1).Value = 0
        Else
            cl.offset(0, 1).Value = val
        End If
    Next
End If
If Not Intersect(Target, Columns("J") Is Nothing Then
    For Each cl in Intersect(Target, Columns("J"))
        val = { your formula used for populating column J }  '## UPDATE THIS WITH YOUR PROPER FORMULA/FUNCTION
        If IsError(val) Then
            cl.Offset(0, 3).Value = 0
        Else
            cl.offset(0, 3).Value = val
        End If
    Next
End Sub

You can use the macro recorder : go to the developer tab in the ribbon then record macro then click on your cell with the formula then click stop recording in ribbon then open up VBA and excel will have already generated the macro for you. 您可以使用宏记录器:转到功能区中的“开发人员”选项卡,然后记录宏,然后单击包含公式的单元格,然后单击“在功能区中停止记录”,然后打开VBA,Excel将为您生成宏。

When I do this I get the following: 当我这样做时,我得到以下信息:

    Sub Macro1()
        Range("A1").Select
    'I have entered my formula in cell A1
        ActiveCell.FormulaR1C1 = _
            "=IFERROR(VLOOKUP(R[10]C[6],Data!R[1]C[1]:R[12]C[3],3,FALSE),0)"
    End Sub

this is the macro I came up with. 这是我想出的宏。 It will cycle through the range you specified and apply the vlookup you are asking for. 它将在您指定的范围内循环并应用您要的vlookup。 This will only run when you actually run the macro. 这只会在您实际运行宏时运行。

Sub Macro1()
Dim startRow as Integer
Dim endRow as Integer
Dim wsData as Worksheet

'just edit the Sheet2 name to the actual sheet name
Set wsData as ActiveWorkbook.Worksheets("Sheet2")
'this is the starting row of your B11 and the end row of your M29
startRow = 11
endRow = 29


'For loop to look at each row in your range on sheet1 that you want to populate
For startRow To endRow
    'This assign the value returned by the vlookup to the cell H of whatever row it is now checking
    wsData.Cells(startRow, 8).Value = Iferror(vlookup(startRow, 7;wsData.Range(Cells(2, 2), Cells(13, 4));3;False);0)
Next startRow

End sub

Tell me if you encounter any issues or have any questions. 告诉我您是否遇到任何问题或疑问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM