简体   繁体   English

Excel VBA:遍历列以识别数据输入行

[英]Excel VBA: Loop through column to identify row for data entry

I am trying to create a table that sorts data by a date range (week).我正在尝试创建一个按日期范围(周)对数据进行排序的表。 I have a userform that has a combo box that lists the date ranges that are existing in the table.我有一个用户表单,它有一个组合框,列出了表中存在的日期范围。 From there, there are a few text boxes I would enter numbers into.从那里,有几个文本框我可以输入数字。 My goal is to have a macro that loops through the rows in the table and stops when it reaches the row with the corresponding date range, then adds the values in the text boxes to corresponding cells in that row.我的目标是有一个宏循环遍历表中的行,并在到达具有相应日期范围的行时停止,然后将文本框中的值添加到该行中的相应单元格。 I think I have the loop set up:我想我已经设置了循环:

** Updated Code: ** 更新代码:

Private Sub Submitb_Click()


intLastCol = Sheets("Sheet1").Cells(1, Columns.Count).End(xlToLeft).Column
intLastRow = Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To intLastRow
    If Sheets("Sheet1").Cells(i, 4).Value = ComboBox1.Value Then
        For j = 5 To intLastCol
            Sheets("Sheet1").Cells(i, j).Value = Sheets("Sheet1").Cells(i, j).Value + Controls("Textbox" & 1).Value
        Next j
    End If
Next i

UserForm1.Hide
Call Form_Initialize

End Sub

That currently adds the value of the first textbox to all 4 cells in the row... Any ideas on how to fix that?目前将第一个文本框的值添加到行中的所有 4 个单元格中......关于如何解决这个问题的任何想法?

This isn't really how Stackoverflow works but I will give you a push in the right direction with some code.这并不是 Stackoverflow 的真正工作方式,但我会用一些代码向您推动正确的方向。 Next time, give it a shot, post the code you have so far, and you are likely to get much better answers/responses.下一次,试一试,发布你到目前为止的代码,你可能会得到更好的答案/响应。

First, there are different ways to approach this.首先,有不同的方法来解决这个问题。 Based on what you are saying, you want it to loop thru, find the matching date, and take the values in that row into the user form.根据您所说的,您希望它循环,找到匹配的日期,并将该行中的值带入用户表单。 I will show you how it would look the way you are talking about.我将向您展示您所说的外观。 There may be more efficient ways to achieve this, but I am sticking to what you are describing.可能有更有效的方法来实现这一点,但我坚持你所描述的。 I will assume you know how to populate the combo box with those dates.我假设您知道如何使用这些日期填充组合框。

Now, we will only want this event to trigger when that combo box is changed, so to start, our sub will look like this:现在,我们只希望当组合框改变时触发这个事件,所以开始时,我们的 sub 看起来像这样:

Private Sub ComboBox1_Change()
'our code will go here
End Sub

Now we need to add some code to loop through your dates, find the match, then go down the row and take the values.现在我们需要添加一些代码来循环遍历您的日期,找到匹配项,然后将 go 向下行并获取值。 For this, we will use a loop within a loop.为此,我们将在循环中使用循环。 But before we do it, we need to define some variables to make it dynamic and make sure it is only working as much as it needs to get the job done - after all, we only want to check cells in that row with dates in them, not every cell in that row.但在我们这样做之前,我们需要定义一些变量以使其动态化,并确保它只在完成工作所需的范围内工作 - 毕竟,我们只想检查该行中包含日期的单元格,而不是该行中的每个单元格。 So lets find the last row, and last column, with text in it.因此,让我们找到其中包含文本的最后一行和最后一列。

intLastCol = Sheets("Sheet1").Cells(2, Columns.Count).End(xlToLeft).Column
intLastRow = Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row

Lets break this down.让我们分解一下。 First, we describe the sheet we want to look at - in this case, its "Sheet1".首先,我们描述我们想要查看的工作表——在本例中,它是“Sheet1”。 Cells follows the format (Row#, Column#).单元格遵循格式(行#、列#)。 So Cells(1, 2) would mean the first row, second column cell.所以Cells(1, 2)表示第一行第二列单元格。 In this case, we want to find out the last column with text in it, so we say Cells(2, Columns.Count).End(xlToLeft).Column .在这种情况下,我们想要找出其中包含文本的最后一列,所以我们说Cells(2, Columns.Count).End(xlToLeft).Column Note that I only look at the second row, whys that?请注意,我只看第二行,为什么呢? Because your headers are in the first row and we don't care about those!因为您的标题在第一行,我们不在乎那些! intLastRow follows the same format, but counts the last row with text in it. intLastRow遵循相同的格式,但计算包含文本的最后一行。 Now we know where the limits are, its time to create our loop!现在我们知道了限制在哪里,是时候创建我们的循环了!

For i = 2 To intLastRow 'start at 2nd row, because we don't want to check the headers row, and only go to the last row of text
    If Sheets("Sheet1").Cells(i, 2).Value = ComboBox1.Value Then 'we are looping down the column, if the text of the value we loop thru matches, then its time for another loop, else continue down the column
        For j = 3 To intLastCol 'starting on the 3rd column, because thats where the data we want is
            Controls("Me.TextBox" & j - 2).Value = Sheets("Sheet1").Cells(i, j).Value 'we go down the row and take the values we see on the sheet and put them in the textbox. Cells(i,j) means i row (where we found the value), and j column (where our values are)
            'Note I do Me.Textbox & j-2, this is because your textboxes are probably named "TextBox1", "TextBox2" etc... but j will only go from 3 to 6... so we take off 2 each time to get to the textbox name
        Next j
    End If
Next i

I have added comments to code above to help explain what I did.我在上面的代码中添加了注释来帮助解释我做了什么。 But in sum, it loops thru each value in your dates column, if it matches what the combo box has, then it will loop thru that row and capture the data there and assign it to your textboxes.但总而言之,它会循环遍历日期列中的每个值,如果它与组合框的内容匹配,那么它将循环遍历该行并在那里捕获数据并将其分配给您的文本框。

So all together, our code will look something like this:所以总的来说,我们的代码看起来像这样:

Private Sub ComboBox1_Change()
    intLastCol = Sheets("Sheet1").Cells(1, Columns.Count).End(xlToLeft).Column
    intLastRow = Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row

    For i = 2 To intLastRow 
        If Sheets("Sheet1").Cells(i, 2).Value = ComboBox1.Value Then 
            For j = 3 To intLastCol 
                Controls("Me.TextBox" & j - 2).Value = Sheets("Sheet1").Cells(i, j).Value 
            Next j
        End If
    Next i        
End Sub

This will get you the majority of the way there.这将使您大部分时间到达那里。 However, you should add error handling, and name some ranges.但是,您应该添加错误处理,并命名一些范围。 You should avoid having a hard-coded value in your loops, such as Cells(i, 2) .您应该避免在循环中使用硬编码值,例如Cells(i, 2) If you ever add a row or column or change the worksheet at all, Cells(i,2) no longer references what it used to.如果您曾经添加行或列或更改工作表, Cells(i,2)不再引用它以前的内容。 There are a plethora of resources available online for VBA and to assist you with this. VBA 有大量的在线资源可以帮助您。 Good luck!祝你好运!

The code below will accomplish what you are trying to do.下面的代码将完成您正在尝试做的事情。

The UserForm_Initialize() macro will load ComboBox1 with every date range`. UserForm_Initialize()宏将在每个日期范围内加载ComboBox1

Private Sub UserForm_Initialize()
    'uses dynamic range to accommodate for new weeks added to the worksheet
    Me.ComboBox1.RowSource = Sheet1.Range("D2:D" & Sheet1.Range("D" & Sheet1.Rows.Count).End(xlUp).Row).Address

End Sub

The CommandButton1_Click() macro will find the date range selected in ComboBox1 in column D, and write each TextBox Value to the right of the cell, offsetting for each TextBox . CommandButton1_Click()宏将在 D 列的ComboBox1中找到选定的日期范围,并将每个TextBox值写入单元格的右侧,为每个TextBox偏移。

Private Sub CommandButton1_Click()
'Define your variables
Dim ws As Worksheet, txbxStr As String, j As Long, i As Long

'Assign your variables
Set ws = ThisWorkbook.Sheets("Sheet1")

    'Loop through the cells in col D
    For j = 2 To Sheet1.Range("D" & Sheet1.Rows.Count).End(xlUp).Row

        'Check if cell value matches ComboBox1's value, if matchs then write the textbox value to the row
        If ws.Cells(j, 4).Value = Me.ComboBox1.Text Then

            'Note; your textboxes must be numbered in sequence, e.g. 1 to 15
            For i = 1 To 15 'Change the second number to the number of textboxes you want to loop through e.g. 72
                txbxStr = Me.Controls("TextBox" & i)
                'Insert each TextBox value in the same row, offsetting 1 cell for each textbox value
                'Note; if your textboxes are numbered 5 to 20, you would have to subtract 4 from i in the line below, e.g. .Offset(, i - 4)
                ws.Cells(j, 4).Offset(, i).Value = txbxStr
            Next i
        End If
    Next j

    'Unload Me 'use if you want to unload the userform
End Sub

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

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