简体   繁体   中英

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?

This isn't really how Stackoverflow works but I will give you a push in the right direction with some code. 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:

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. 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". Cells follows the format (Row#, Column#). So Cells(1, 2) would mean the first row, second column cell. 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 . 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. 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) . If you ever add a row or column or change the worksheet at all, Cells(i,2) no longer references what it used to. There are a plethora of resources available online for VBA and to assist you with this. Good luck!

The code below will accomplish what you are trying to do.

The UserForm_Initialize() macro will load ComboBox1 with every date range`.

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 .

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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