简体   繁体   English

VBA:从较大的表中调用多个行

[英]VBA: Calling multiple rows from a larger table

I want to insert rows from an excel table into a 'results' sheet if the values in column A of the table match a value specified by the user on the results sheet. 如果表的A列中的值与用户在结果表上指定的值匹配,我想将excel表中的行插入到“结果”表中。

Firstly I would like to ask if there is a more efficient way to do this than what I have embarked on, and if not I would appreciate some help with my attempt. 首先,我想问一问,是否有比我所从事的方法更有效的方法,如果没有,我将不胜感激。

I was planning on the following 我正在计划以下

  1. sorting the data table by column A so that if new items have been added they appear in alphabetical order 按A列对数据表进行排序,以便在添加新项目时按字母顺序显示
  2. Using WorksheetFunction.CountIf to determine the number of rows matching the criteria & setting this as a variable 使用WorksheetFunction.CountIf确定符合条件的行数并将其设置为变量
  3. Using WorksheetFunction.Match to find the first matching Row & setting this value as a variable 使用WorksheetFunction.Match查找第一个匹配的行并将此值设置为变量
  4. using established variables to copy the relevant values over to the results tab 使用已建立的变量将相关值复制到结果选项卡

     Sub CheckPrevious() Dim RowCount As Integer Dim FirstRow As Integer Dim Rng As Range Dim MatchRng As Range Dim MatchItem As Variant Rng = Sheets("Database").Range("A1:P200") MatchRng = Sheets("Database").Range("A1:A200") MatchItem = Sheets("Menu").Range("C9") RowCount = WorksheetFunction.CountIf(Worksheets("Database").Range("A:A"), _ Worksheets("Menu").Range("C9").Value) FirstRow = WorksheetFunction.Match(MatchRng, MatchItem, 0) Sheets("Pricing").Range("A2:E6").ClearContents Worksheets("Database").AutoFilter.Sort.SortFields.Clear Worksheets("Database").AutoFilter.Sort.SortFields.Add Key:= _ Range("A1:A7"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _ xlSortNormal With ActiveWorkbook.Worksheets("Database").AutoFilter.Sort .Header = xlYes .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With If RowCount > 1 Then Sheets("Pricing").Range("A2").Value = Worksheets("Database").Range("A" & FirstRow).Value Sheets("Pricing").Range("B2").Value = Worksheets("Database").Range("B" & FirstRow).Value Sheets("Pricing").Range("C2").Value = Worksheets("Database").Range("C" & FirstRow).Value Sheets("Pricing").Range("D2").Value = Worksheets("Database").Range("D" & FirstRow).Value Sheets("Pricing").Range("E2").Value = Worksheets("Database").Range("E" & FirstRow).Value FirstRow = FirstRow + 1 End If If RowCount > 2 Then Sheets("Pricing").Range("A3").Value = Worksheets("Database").Range("A" & FirstRow).Value Sheets("Pricing").Range("B3").Value = Worksheets("Database").Range("B" & FirstRow).Value Sheets("Pricing").Range("C3").Value = Worksheets("Database").Range("C" & FirstRow).Value Sheets("Pricing").Range("D3").Value = Worksheets("Database").Range("D" & FirstRow).Value Sheets("Pricing").Range("E3").Value = Worksheets("Database").Range("E" & FirstRow).Value FirstRow = FirstRow + 1 End If If RowCount > 3 Then Sheets("Pricing").Range("A4").Value = Worksheets("Database").Range("A" & FirstRow).Value Sheets("Pricing").Range("B4").Value = Worksheets("Database").Range("B" & FirstRow).Value Sheets("Pricing").Range("C4").Value = Worksheets("Database").Range("C" & FirstRow).Value Sheets("Pricing").Range("D4").Value = Worksheets("Database").Range("D" & FirstRow).Value Sheets("Pricing").Range("E4").Value = Worksheets("Database").Range("E" & FirstRow).Value FirstRow = FirstRow + 1 End If If RowCount > 4 Then Sheets("Pricing").Range("A5").Value = Worksheets("Database").Range("A" & FirstRow).Value Sheets("Pricing").Range("B5").Value = Worksheets("Database").Range("B" & FirstRow).Value Sheets("Pricing").Range("C5").Value = Worksheets("Database").Range("C" & FirstRow).Value Sheets("Pricing").Range("D5").Value = Worksheets("Database").Range("D" & FirstRow).Value Sheets("Pricing").Range("E5").Value = Worksheets("Database").Range("E" & FirstRow).Value FirstRow = FirstRow + 1 End If End Sub 

Am currently getting a type mismatch error on my WorksheetFunction.Match 我的WorksheetFunction.Match当前收到类型不匹配错误

Thanks in advance for any help! 在此先感谢您的帮助!

Looks like you have got the order of MATCH 's arguments mixed up, the first argument should be the value you're looking for while the second should be the range you search over. 看起来您已经混合了MATCH的参数顺序,第一个参数应该是您要查找的值,而第二个参数应该是您要搜索的范围。 You have them the other way round. 反之,则有它们。

In response to your request, I've edited your code a bit to make it more compact: 为了响应您的请求,我对您的代码进行了一些编辑以使其更加紧凑:

Sub CheckPrevious()
    Dim RowCount As Long
    Dim FirstRow As Long
    Dim RowOffset As Long
    Dim ColumnOffset As Long
    Dim Rng As Range
    Dim MatchRng As Range
    Dim MatchItem As String

    Set Rng = ThisWorkbook.Worksheets("Database").Range("A1:P200")
    Set MatchRng = ThisWorkbook.Worksheets("Database").Range("A1:A200")
    MatchItem = ThisWorkbook.Worksheets("Menu").Range("C9")
    RowCount = Application.WorksheetFunction.CountIf(Worksheets("Database").Range("A:A"), MatchItem)
    FirstRow = Application.WorksheetFunction.Match(MatchItem, MatchRng, 0)

    ThisWorkbook.Worksheets("Pricing").Range("A2:E6").ClearContents

    With ThisWorkbook.Worksheets("Database").AutoFilter.Sort
        .SortFields.Clear
        .SortFields.Add Key:=Range("A1:A11"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With


    For RowOffset = 0 To RowCount - 1
        For ColumnOffset = 0 To 4
            ThisWorkbook.Worksheets("Pricing").Range("A2").Offset(RowOffset, ColumnOffset).Value2 _
                    = ThisWorkbook.Worksheets("Database").Range("A" & FirstRow).Offset(RowOffset, ColumnOffset).Value2
        Next ColumnOffset
    Next RowOffset
End Sub

I won't go into all the details on how it works now, but I'll say that the main improvement over what you had written is the outer for-loop which completely eliminates the if-statements you had in your code. 我不会详细介绍它现在如何工作,但是我会说,您编写的内容的主要改进是外部for循环,该循环完全消除了代码中的if语句。

I was a bit uncertain about whether or not the inner for-loop was necessary, as it decreases readability quite a bit, but decided on leaving it in, if for no other reason than to demonstrate further how to use OFFSET to refer to cells. 我不确定内部的for循环是否必要,因为它会大大降低可读性,但是我决定放弃它,除非是为了进一步说明如何使用OFFSET来引用单元格。

You should also notice that if C9 in the Menu-sheet is left blank, there is a good chance your code will crash - so maybe add in a check for that. 您还应该注意,如果“菜单”表中的C9留为空白,则您的代码很有可能会崩溃-因此,请为此进行检查。

In conclusion I won't say that this is exactly how I'd have solved your task if I was the one to create a solution in the first place, but hopefully my editing of your code will give you some insight into a somewhat different approach to the problem. 总而言之,如果我是一个首先创建解决方案的人,我不会说这正是我要解决的任务,但是希望我对代码的编辑将使您对有些不同的方法有所了解解决问题。

This was what the three sheets I copied into my workbook looked like after I attempted running the code: 这是我尝试运行代码后复制到工作簿中的三张纸的样子:

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明

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

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