Excel VBA – 根据3个标准​​(来自另一个工作表中的值)在一张表上填充一个列(带有通配符的复杂IF和相关VBA)

我是新的Excel VBA,尽pipe我的努力,我似乎​​无法find一个类似的例子在线使用作为我的问题的解决scheme。

我正在创build一个与汽车库存有关的数据表。 我设置的工作簿有两个选项卡。 第一个标签为“FEEDER”,包含硬编码input(汽车值)表。 第二个标签为“Sheet1”,包含所有库存的原始数据。 工作表1要求列“I”中的汽车值。 我的目标是设置工作簿,以便在“Sheet1”中标记“值”的列I将通过从FEEDER表格的值input中单击button来自动填充。 对我来说,棘手的部分是价值是基于1)汽车types(即轿车/皮卡/等),2)颜色(不同的颜色有稍微不同的值),3)制造年份。 我刚开始接触这个IF IF和声明,但认为创build一个macros将是一个更有效的途径。

我有一份工作清单,但还有更多types的汽车(总共400多辆)。 如果我能在这个阶段得到一些帮助,我可以[希望]找出其他的问题。

你的帮助将不胜感激。

屏幕截图: FEEDER表和SHEET1库存清单

我的代码:

Sub ValueFill() Dim x As Integer For x = 3 To Range("A" & Rows.Count).End(xlUp).Row If UCase(Sheets("Sheet1").Range("A" & x).Text) = "Pickup*" And UCase(Sheets("Sheet1").Text("C" & x).Value) = "Red*" Then Range("I" & x).Formula = Application.WorksheetFunction.Index(Sheets("FEEDER").Range("C" & Rows.Count).End(xlUp).Row, Application.WorksheetFunction.Match(Sheets("Sheet1").Range("f" & x), Sheets("Feeder").Range("b" & Rows.Count).End(xlUp).Row, 0), 1) ElseIf UCase(Sheets("Sheet1").Range("A" & x).Text) = "Pickup*" And UCase(Sheets("Sheet1").Text("C" & x).Value) = "Blue*" Then Range("I" & x).Formula = Application.WorksheetFunction.Index(Sheets("FEEDER").Range("D" & Rows.Count).End(xlUp).Row, Application.WorksheetFunction.Match(Sheets("Sheet1").Range("f" & x), Sheets("Feeder").Range("b" & Rows.Count).End(xlUp).Row, 0), 1) ElseIf UCase(Sheets("Sheet1").Range("A" & x).Text) = "Sedan*" And UCase(Sheets("Sheet1").Text("C" & x).Value) = "Red*" Then Range("I" & x).Formula = Application.WorksheetFunction.Index(Sheets("FEEDER").Range("E" & Rows.Count).End(xlUp).Row, Application.WorksheetFunction.Match(Sheets("Sheet1").Range("f" & x), Sheets("Feeder").Range("b" & Rows.Count).End(xlUp).Row, 0), 1) ElseIf UCase(Sheets("Sheet1").Range("A" & x).Text) = "Sedan*" And UCase(Sheets("Sheet1").Text("C" & x).Value) = "Blue*" Then Range("I" & x).Formula = Application.WorksheetFunction.Index(Sheets("FEEDER").Range("F" & Rows.Count).End(xlUp).Row, Application.WorksheetFunction.Match(Sheets("Sheet1").Range("f" & x), Sheets("Feeder").Range("b" & Rows.Count).End(xlUp).Row, 0), 1) 'I would keep "ElseIf-ing" for each combination of auto type and color, then index match by year... Else: Range("I" & x).Text = "Error" End If Next End Sub 

我的下意识反应是使用两种不同的function,因为颜色和types是相互依赖的:一个用于处理年份,一个用于处理车辆的types和颜色。 就像是

 Sub ValueFill() For car = 1 to last 'this is your loop over the cars in Sheet1 color = type_color(car) year = get_year(car) price = Sheets("FEEDER").Cells(year, color).value Function get_year(car) 'gets the year value for a give car and returns the corresponding row number of that year, ie car year 2009 is row 10 in FEEDER End Function Function type_color() 'will first get the type then convert based on color 'gets the type of the car and returns the left column index for that type 'ie type = pickup then column index = 3 (Column C) if color not same as column value from above then offset it 'ie for a blue pickup column index + 1 -> 4 end function 

这里是你的示例代码的部分重写。 完成模块是不够的,但也许可以让你开始。

 Sub ValueFill() Dim x As Long, wsf As Worksheet, app As Application Set app = Application Set wsf = Sheets("FEEDER") With Sheets("Sheet1") For x = 3 To .Cells(Rows.Count, 1).End(xlUp).Row Select Case Left(LCase(.Cells(x, 1).Text), 5) Case "picku" Select Case Left(LCase(.Cells(x, 3).Text), 3) Case "red" 'unclear on whether you want a value or a formula - pick one of these .Range("I" & x).Value = app.Index(wsf.Columns(3), app.Match(.Cells(x, 6).Value, wsf.Columns(2), 0)) '.Range("I" & x).Formula = "=INDEX(Feeder!C:C, MATCH(F" & x & ", Feeder!B:B, 0))" '.Range("I" & x).FormulaR1C1 = "=INDEX(Feeder!C3, MATCH(RC6, Feeder!C2, 0))" Case "blu" .Range("I" & x).Value = app.Index(wsf.Columns(4), app.Match(.Cells(x, 6).Value, wsf.Columns(2), 0)) Case Else 'do nothing End Select Case "sedan" Select Case Left(LCase(.Cells(x, 3).Text), 3) Case "red" .Range("I" & x).Value = app.Index(wsf.Columns(5), app.Match(.Cells(x, 6).Value, wsf.Columns(2), 0)) Case "blu" .Range("I" & x).Value = app.Index(wsf.Columns(6), app.Match(.Cells(x, 6).Value, wsf.Columns(2), 0)) Case Else 'do nothing End Select Case Else Debug.Print "not it" End Select Next x End With Set wsf = Nothing Set app = Nothing End Sub 

如果提供了有关FEEDER工作表性质的更多信息,则可以开发一个通用的公式。

其实我不熟悉excel的function。 但是,我只能使用vba代码。

谢谢,这是个很好的问题。 试一试我的想法。

在这里,我的方法为你的问题。 你不需要任何修改。 只需复制并运行。 它运作良好。

 Public Sub fillValue() Dim inventorySheet, priceSheet As Worksheet Dim inventoryRow, priceRow As Integer Dim redPickup, bluePickup, redSedan, blueSedan, redRoadster, blueRoadster As String Dim automobileType, automobileColor, automobilePrice As String Dim isFound As Boolean 'Set sheet for common use. Set inventorySheet = ThisWorkbook.Worksheets("Sheet1") Set priceSheet = ThisWorkbook.Worksheets("FEEDER") 'Price list in FEEDER sheet are stable. 'So, we can use them as constant. 'I initialize them as follow. You can add more column. redPickup = "C" bluePickup = "D" redSedan = "E" blueSedan = "F" redRoadster = "G" blueRoadster = "H" 'Set the start row Sheet1 sheet inventoryRow = 3 'Looping all data from "Sheet1" sheet. 'One thing that the main colum is Automobile Type. So, loop until it is blank. Do While inventorySheet.Range("A" & inventoryRow) <> "" 'First, get the price row from FEEDER sheet for manufacture year. 'Reset flag. isFound = False 'Set the start row of FEEDER sheet. priceRow = 4 'Loop manufacture year column of FEEDER sheet until blank Do While priceSheet.Range("B" & priceRow) <> "" If priceSheet.Range("B" & priceRow) = inventorySheet.Range("F" & inventoryRow) Then 'Set true for exist record for manufacture year isFound = True 'Exit loop Exit Do End If priceRow = priceRow + 1 Loop 'If there is no record for price, we should not do anything. 'If price record for manufacture year is exist, take the price. If isFound Then 'Second, getting the automobile type from Sheet1. 'Get Automobile Type from sheet automobileType = inventorySheet.Range("A" & inventoryRow) 'Split by space splitedValues = Split(Trim(automobileType), " ") 'Get last word for automobile type automobileType = splitedValues(UBound(splitedValues)) 'Third, get the automobile color. 'Get Automobile Color from sheet. automobileColor = inventorySheet.Range("C" & inventoryRow) 'Split by "-" splitedValues = Split(Trim(automobileColor), "-") 'Get first word for automobile type automobileColor = splitedValues(LBound(splitedValues)) 'Reset automobile price. automobilePrice = "" 'Fouth, check type and color and get price Select Case automobileType Case "Roadster" If automobileColor = "Red" Then automobilePrice = priceSheet.Range(redRoadster & priceRow) Else automobilePrice = priceSheet.Range(blueRoadster & priceRow) End If Case "Sedan" If automobileColor = "Red" Then automobilePrice = priceSheet.Range(redSedan & priceRow) Else automobilePrice = priceSheet.Range(blueSedan & priceRow) End If Case "Pickup" If automobileColor = "Red" Then automobilePrice = priceSheet.Range(redPickup & priceRow) Else automobilePrice = priceSheet.Range(bluePickup & priceRow) End If End Select 'Fifth, set the price in inventory sheet. inventorySheet.Range("I" & inventoryRow) = automobilePrice Else 'Set error for miss. inventorySheet.Range("I" & inventoryRow) = "Error" End If 'Increase inventory row inventoryRow = inventoryRow + 1 Loop End Sub 

在这里,我的证据表明你的问题。

我准备“Sheet1”工作表的数据。

在这里输入图像描述

我为“FEEDER”表单准备数据。

在这里输入图像说明

运行代码后,我得到了这个结果。

在这里输入图像说明

有一个很好的工作..!