I want to add new data to a table with a form. I have it adding data at the bottom of the sheet.
I want the new info at the top.
With my code, it sends the data to two sheets, the "home" sheet and the sheet that is selected in the first combo box.
Private Sub CommandButton1_Click()
TargetSheet = ComboBox1.Value
If TargetSheet = "" Then
Exit Sub
End If
Worksheets(TargetSheet).Activate
lastrow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
ActiveSheet.Cells(lastrow + 1, 1).Value = TextBox1.Value
ActiveSheet.Cells(lastrow + 1, 2).Value = TextBox2.Value
ActiveSheet.Cells(lastrow + 1, 3).Value = TextBox3.Value
ActiveSheet.Cells(lastrow + 1, 4).Value = TextBox4.Value
ActiveSheet.Cells(lastrow + 1, 5).Value = TextBox5.Value
ActiveSheet.Cells(lastrow + 1, 6).Value = TextBox6.Value
ActiveSheet.Cells(lastrow + 1, 7).Value = TextBox7.Value
ActiveSheet.Cells(lastrow + 1, 8).Value = TextBox8.Value
Worksheets("Home").Activate
lastrow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
ActiveSheet.Cells(lastrow + 1, 1).Value = ComboBox1.Value
ActiveSheet.Cells(lastrow + 1, 2).Value = TextBox1.Value
ActiveSheet.Cells(lastrow + 1, 3).Value = TextBox2.Value
ActiveSheet.Cells(lastrow + 1, 4).Value = TextBox3.Value
ActiveSheet.Cells(lastrow + 1, 5).Value = TextBox4.Value
ActiveSheet.Cells(lastrow + 1, 6).Value = TextBox5.Value
ActiveSheet.Cells(lastrow + 1, 7).Value = TextBox6.Value
ActiveSheet.Cells(lastrow + 1, 8).Value = TextBox7.Value
ActiveSheet.Cells(lastrow + 1, 9).Value = TextBox8.Value
ActiveSheet.Cells(lastrow + 1, 10).Value = Date
ActiveSheet.Cells(lastrow + 1, 11).Value = TimeValue(Now)
ActiveSheet.Cells(lastrow + 1, 12).Value = TextBox9.Value
MsgBox ("Item Added Successfully.")
TextBox1.Value = ""
TextBox2.Value = ""
TextBox3.Value = ""
TextBox4.Value = ""
Worksheets("Home").Activate
Worksheets("Home").Cells(1, 1).Select
End Sub
How do I put the new data in the second row since I have headers on the sheet?
There are a lot of stuff to improve your my code, but I want to keep it simple
Some things to begin:
Use option explicit so you don't have unexpected behavior with undefined variables
Always indent your code (see www.rubberduckvba.com a free tool that helps you with that)
Try to separate your logic defining variables and the reusing them
Name your forms' controls
Check a great article about UserForms (when you feel you're ready to advance)
Check the code's comments, and adapt it to fit your needs
EDIT: No need for the EntireRow qualifier as we are already selecting the whole row, and added the copy format from below
Code:
Private Sub CommandButton1_Click()
' Define object variables
Dim targetSheet As Worksheet
Dim homeSheet As Worksheet
Dim targetSheetName As String
Dim homeSheetName As String
Dim targetSheetTopRow As Long
Dim homeSheetTopRow As Long
Dim textBox1Value As Variant
Dim textBox2Value As Variant
Dim textBox3Value As Variant
Dim textBox4Value As Variant
Dim textBox5Value As Variant
Dim textBox6Value As Variant
Dim textBox7Value As Variant
Dim textBox8Value As Variant
Dim textBox9Value As Variant
' Define parameters
targetSheetTopRow = 2
homeSheetTopRow = 2
homeSheetName = "Home"
' Validate if combobox has any value
If Me.ComboBox1.Value = vbNullString Then Exit Sub
' Get target sheet name
targetSheetName = Me.ComboBox1.Value
' Add a reference to sheets
Set targetSheet = ThisWorkbook.Worksheets(targetSheetName)
Set homeSheet = ThisWorkbook.Worksheets(homeSheetName)
' Store current controls values
textBox1Value = Me.TextBox1.Value
textBox2Value = Me.TextBox2.Value
textBox3Value = Me.TextBox3.Value
textBox4Value = Me.TextBox4.Value
textBox5Value = Me.TextBox5.Value
textBox6Value = Me.TextBox6.Value
textBox7Value = Me.TextBox7.Value
textBox8Value = Me.TextBox8.Value
' No need to activate stuff
With targetSheet
' Insert a row after row 2
.Range(targetSheetTopRow & ":" & targetSheetTopRow).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromRightOrBelow
' Add cells values
.Cells(targetSheetTopRow, 1).Value = textBox1Value
.Cells(targetSheetTopRow, 2).Value = textBox2Value
.Cells(targetSheetTopRow, 3).Value = textBox3Value
.Cells(targetSheetTopRow, 4).Value = textBox4Value
.Cells(targetSheetTopRow, 5).Value = textBox5Value
.Cells(targetSheetTopRow, 6).Value = textBox6Value
.Cells(targetSheetTopRow, 7).Value = textBox7Value
.Cells(targetSheetTopRow, 8).Value = textBox8Value
End With
With homeSheet
' Insert a row after row 2
.Range(homeSheetTopRow & ":" & homeSheetTopRow).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromRightOrBelow
' Add cells values
.Cells(homeSheetTopRow, 1).Value = textBox1Value
.Cells(homeSheetTopRow, 2).Value = textBox2Value
.Cells(homeSheetTopRow, 3).Value = textBox3Value
.Cells(homeSheetTopRow, 4).Value = textBox4Value
.Cells(homeSheetTopRow, 5).Value = textBox5Value
.Cells(homeSheetTopRow, 6).Value = textBox6Value
.Cells(homeSheetTopRow, 7).Value = textBox7Value
.Cells(homeSheetTopRow, 8).Value = textBox8Value
.Cells(homeSheetTopRow, 9).Value = Date
.Cells(homeSheetTopRow, 10).Value = TimeValue(Now)
.Cells(homeSheetTopRow, 11).Value = textBox9Value
End With
' Clear control's values
Me.TextBox1.Value = vbNullString
Me.TextBox2.Value = vbNullString
Me.TextBox3.Value = vbNullString
Me.TextBox4.Value = vbNullString
' Alert user
MsgBox ("Item Added Successfully.")
' Goto...
homeSheet.Activate
homeSheet.Cells(1, 1).Select
End Sub
Let me know if it works or you need more help
Related
I am New to VBA, so my codes are usually very slow/suboptimized.
In one of my programs I have cells in the sheet that has to be filled when the user press a button, the renges change depending on the button but the concept is the same.
So I did this monstrosity:
Cells((Range("namedrange").Row + 5), 1).Value = ThisWorkbook.Sheets(5).Cells(4, 7).Value
Cells((Range("namedrange").Row + 5), 3).Value = ThisWorkbook.Sheets(5).Cells(4, 8).Value
Cells((Range("namedrange").Row + 5), 5).Value = ThisWorkbook.Sheets(5).Cells(4, 9).Value
Cells((Range("namedrange").Row + 5), 8).Value = ThisWorkbook.Sheets(5).Cells(4, 10).Value
Cells((Range("namedrange").Row + 5) + 1, 1).Value = ThisWorkbook.Sheets(5).Cells(5, 7).Value
Cells((Range("namedrange").Row + 5) + 1, 3).Value = ThisWorkbook.Sheets(5).Cells(5, 8).Value
Cells((Range("namedrange").Row + 5) + 1, 5).Value = ThisWorkbook.Sheets(5).Cells(5, 9).Value
Cells((Range("namedrange").Row + 5) + 1, 8).Value = ThisWorkbook.Sheets(5).Cells(5, 10).Value
but later changed to:
With Range("namedrange")
.Offset(5).Columns(1).Value = ThisWorkbook.Sheets(3).Cells(4, 7).Value
.Offset(5).Columns(3).Value = ThisWorkbook.Sheets(3).Cells(4, 8).Value
.Offset(5).Columns(5).Value = ThisWorkbook.Sheets(3).Cells(4, 9).Value
.Offset(5).Columns(8).Value = ThisWorkbook.Sheets(3).Cells(4, 10).Value
.Offset(6).Columns(1).Value = ThisWorkbook.Sheets(3).Cells(5, 7).Value
.Offset(6).Columns(3).Value = ThisWorkbook.Sheets(3).Cells(5, 8).Value
.Offset(6).Columns(5).Value = ThisWorkbook.Sheets(3).Cells(5, 9).Value
.Offset(6).Columns(8).Value = ThisWorkbook.Sheets(3).Cells(5, 10).Value
End With
which is a bit faster, however I feel that it is still suboptimized. And I would like to know if there is a way to make it cleaner/more elegant.
Just to be noted that there are discontinuities in the columns, e.g. it starts in the 1st columns but jumps to the 3rd and then to the 5th and at last to the 8th.
The code works but it is slow, I just want a way to make it faster/cleaner.
Using Variables
In regards to efficiency, that's about it: you're using the most efficient way to copy values from one cell to another aka copying by assignment.
If you want it to be more flexible, maintainable, and readable(?), here are some ideas.
Additionally, you can move the remaining magic numbers and text to constants at the beginning of the code or even use the constants as arguments.
Sub CopyValues()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Specify the worksheet if you know it.
'Dim dnrg As Range: Set dnrg = wb.Sheets("Sheet1").Range("NamedRange")
' Otherwise, make sure the workbook is active.
If Not wb Is ActiveWorkbook Then wb.Activate
Dim dnrg As Range: Set dnrg = Range("NamedRange")
Dim drg As Range: Set drg = dnrg.Range("A1,C1,E1,H1").Offset(5)
Dim cCount As Long: cCount = drg.Cells.Count
' If you know the tab name, use it instead of the index (3).
Dim sws As Worksheet: Set sws = wb.Sheets(3)
Dim srg As Range: Set srg = sws.Range("G4").Resize(, cCount)
Dim r As Long, c As Long
For r = 0 To 1
For c = 1 To cCount
drg.Offset(r).Cells(c).Value = srg.Offset(r).Cells(c).Value
Next c
Next r
End Sub
Accessing Excel for values from VBA is a slow operation and this adds up when you make multiple requests. When you are essentially retrieving the same information on a repetitive basis there are two two methods can be used to reduce access times.
Replace a lookup with a calculated value
Use a with statement
Thus you code could be written as
Dim myCol as long
myCol =Range("namedrange").Row + 5
With ThisWorkook.Sheets(5)
Cells(myCol, 1).Value = .Cells(4, 7).Value
Cells(myCol, 3).Value = .Cells(4, 8).Value
Cells(myCol, 5).Value = .Cells(4, 9).Value
Cells(myCol, 8).Value = .Cells(4, 10).Value
myCol=myCol+1 ' trivial example
Cells(mycol, 1).Value = .Cells(5, 7).Value
Cells(myCol, 3).Value = .Cells(5, 8).Value
Cells(myCol, 5).Value = .Cells(5, 9).Value
Cells(myCol, 8).Value = .Cells(5, 10).Value
End with
Please also install the free, opensource, and fantastic Rubberduck addin for VBA. The code inspections will help you write VBA that is much more correct.
I wonder what would happen if you use all the .Offset parameters, row and column. Example:
With Range("namedrange")
.Offset(5, 0).Value = ThisWorkbook.Sheets(3).Cells(4, 7).Value
.Offset(5, 2).Value = ThisWorkbook.Sheets(3).Cells(4, 8).Value
.Offset(5, 4).Value = ThisWorkbook.Sheets(3).Cells(4, 9).Value
.Offset(5, 7).Value = ThisWorkbook.Sheets(3).Cells(4, 10).Value
.Offset(6, 0).Value = ThisWorkbook.Sheets(3).Cells(5, 7).Value
.Offset(6, 2).Value = ThisWorkbook.Sheets(3).Cells(5, 8).Value
.Offset(6, 4).Value = ThisWorkbook.Sheets(3).Cells(5, 9).Value
.Offset(6, 7).Value = ThisWorkbook.Sheets(3).Cells(5, 10).Value
End With
You can try to disable screenupdating during execution.
Disable ScreenUpdating
To disable ScreenUpdating, at the beginning of your code put this line:
Application.ScreenUpdating = False
Enable ScreenUpdating
To re-enable ScreenUpdating, at the end of your code put this line:
Application.ScreenUpdating = True
I am a complete novice at Excel VBA and I am currently attempting a project on Excel VBA. I have created a UserForm that would allow the user to enter data onto the Excel Sheet by completing the fields in the UserForm. I have tested all the codes individually and they have worked fine.
For the user to access the UserForm, I have added an ActiveX Command Button on a separate sheet on the same workbook. However, when accessing the UserForm from the ActiveX Command Button, some of the codes do not run (mainly the code that flags out the duplicate entry, as well as the code that generates serial numbers).
Where did I go wrong in my code?
This is my code to adding new data as well as the code to flag out duplicate entries. When opening the UserForm from the ActiveX Command Button, adding new data works fine but it does not flag out duplicate entries in the data. (However, testing the code itself in VBA works perfectly fine).
Private Sub cmdAddNewCustomer_Click()
Dim count As Long
Dim lastrow As Long
Dim lCustomerID As String
Dim ws As Worksheet
Set ws = Worksheets("Customer Data")
'find first empty row in database
lrow = ws.Cells.Find(what:="*", searchorder:=xlRows, _
Searchdirection:=xlPrevious, LookIn:=xlValues).Row + 1
lCustomerID = txtCustomerID
count = 0
With ws
For currentrow = 1 To lrow
If lCustomerID = Cells(currentrow, 1) Then
count = count + 1
End If
If count > 1 Then
.Cells(currentrow, 1).Value = ""
.Cells(currentrow, 2).Value = ""
.Cells(currentrow, 3).Value = ""
.Cells(currentrow, 4).Value = ""
.Cells(currentrow, 5).Value = ""
.Cells(currentrow, 6).Value = ""
.Cells(currentrow, 7).Value = ""
.Cells(currentrow, 8).Value = ""
.Cells(currentrow, 9).Value = ""
.Cells(currentrow, 10).Value = ""
.Cells(currentrow, 11).Value = ""
.Cells(currentrow, 12).Value = ""
.Cells(currentrow, 13).Value = ""
.Cells(currentrow, 14).Value = ""
MsgBox ("CustomerID already exists!")
End If
If count = 0 Then
.Cells(lrow, 1).Value = Me.txtCustomerID.Value
.Cells(lrow, 2).Value = Me.txtCustomerName.Value
.Cells(lrow, 3).Value = Me.cboCustomerStatus.Value
.Cells(lrow, 4).Value = Me.txtContactPerson.Value
.Cells(lrow, 5).Value = Me.cboDepartment.Value
.Cells(lrow, 6).Value = Me.txtPosition.Value
.Cells(lrow, 7).Value = Me.cboRoleType.Value
.Cells(lrow, 8).Value = Me.txtofficeHP1.Value
.Cells(lrow, 9).Value = Me.txtOfficeHP2.Value
.Cells(lrow, 10).Value = Me.txtMobileHP1.Value
.Cells(lrow, 11).Value = Me.txtMobileHP2.Value
.Cells(lrow, 12).Value = Me.txtEmail1.Value
.Cells(lrow, 13).Value = Me.txtEmail2.Value
.Cells(lrow, 14).Value = Me.txtEmail3.Value
End If
Next currentrow
End With
'clear the data
Me.txtCustomerName.Value = ""
Me.cboCustomerStatus.Value = ""
Me.txtContactPerson.Value = ""
Me.cboDepartment.Value = ""
Me.txtPosition.Value = ""
Me.cboRoleType.Value = ""
Me.txtofficeHP1.Value = ""
Me.txtOfficeHP2.Value = ""
Me.txtMobileHP1.Value = ""
Me.txtMobileHP2.Value = ""
Me.txtEmail1.Value = ""
Me.txtEmail2.Value = ""
Me.txtEmail3.Value = ""
End Sub
This is the code to generate serial numbers. (Same problem, does not work when accessed via ActiveX Command Button but works fine when tested individually in VBA).
Sub FindCustomerID()
Dim lastrow
Dim lastnum As Long
Dim ws As Worksheet
Set ws = Worksheets("Customer Data")
If Me.cboCountry = "" Or Me.txtCustomerName = "" Then
Exit Sub
End If
serialno = 1
lastrow = ws.Cells(Rows.count, 1).End(xlUp).Row
CountryCode = UCase(Left(Me.cboCountry, 3))
CustomerCode = UCase(Left(Me.txtCustomerName, 10))
'assemble them into CustomerID
CustomerID = CountryCode & CustomerCode & serialno
For currentrow = 2 To lastrow
If CustomerID = Cells(currentrow, 1) Then
'find last number that applies
serialno = serialno + 1
End If
're-assign customerID with new serial number
CustomerID = CountryCode & CustomerCode & serialno
Next currentrow
Me.lblCustomerID = CustomerID
End Sub
And lastly, this is the code from the ActiveX Command Button that brings out the UserForm.
Private Sub cmdNCustomerData_Click()
frmCustomerdata.Show
End Sub
The cause of the problem you described is a missing . to qualify Cells(currentrow, 1). Because you added the ActiveX button to a different sheet, the line
If lCustomerID = Cells(currentrow, 1) Then
accesses Cells(currentrow, 1) of that sheet. To fix this the range needs to be qualified with a . to become
If lCustomerID = .Cells(currentrow, 1) Then
I would also take
If count = 0 Then
.
.
.
End If
outside the loop. You are repeating these lines many times unnecessarily.
The first block of code then becomes:
Private Sub cmdAddNewCustomer_Click()
Dim count As Long
Dim lastrow As Long
Dim lCustomerID As String
Dim ws As Worksheet
Set ws = Worksheets("Customer Data")
'find first empty row in database
lrow = ws.Cells.Find(what:="*", searchorder:=xlRows, _
Searchdirection:=xlPrevious, LookIn:=xlValues).Row + 1
lCustomerID = txtCustomerID
count = 0
With ws
' Count backward to delete rows completely
For currentrow = lrow - 1 To 1 Step -1
If lCustomerID = .Cells(currentrow, 1) Then
count = count + 1
End If
If count > 1 Then
.Cells(currentrow, 1).Resize(1, 14).ClearContents
' Uncomment the following line to delete the whole row completely
'.Rows(currentrow).Delete
End If
Next currentrow
If count > 1 Then
MsgBox (count - 1 " duplicates of CustomerID found and cleared!")
ElseIf count = 0 Then
.Cells(lrow, 1).Value = Me.txtCustomerID.Value
.Cells(lrow, 2).Value = Me.txtCustomerName.Value
.Cells(lrow, 3).Value = Me.cboCustomerStatus.Value
.Cells(lrow, 4).Value = Me.txtContactPerson.Value
.Cells(lrow, 5).Value = Me.cboDepartment.Value
.Cells(lrow, 6).Value = Me.txtPosition.Value
.Cells(lrow, 7).Value = Me.cboRoleType.Value
.Cells(lrow, 8).Value = Me.txtofficeHP1.Value
.Cells(lrow, 9).Value = Me.txtOfficeHP2.Value
.Cells(lrow, 10).Value = Me.txtMobileHP1.Value
.Cells(lrow, 11).Value = Me.txtMobileHP2.Value
.Cells(lrow, 12).Value = Me.txtEmail1.Value
.Cells(lrow, 13).Value = Me.txtEmail2.Value
.Cells(lrow, 14).Value = Me.txtEmail3.Value
End If
End With
'clear the data
Me.txtCustomerName.Value = ""
Me.cboCustomerStatus.Value = ""
Me.txtContactPerson.Value = ""
Me.cboDepartment.Value = ""
Me.txtPosition.Value = ""
Me.cboRoleType.Value = ""
Me.txtofficeHP1.Value = ""
Me.txtOfficeHP2.Value = ""
Me.txtMobileHP1.Value = ""
Me.txtMobileHP2.Value = ""
Me.txtEmail1.Value = ""
Me.txtEmail2.Value = ""
Me.txtEmail3.Value = ""
End Sub
In the FindCustomerID subroutine you have exactly the same problem with the line
If CustomerID = Cells(currentrow, 1) Then
as Cells(currentrow, 1) is not qualified and therefore, should become
If CustomerID = ws.Cells(currentrow, 1) Then
You are also reassigning the CustomerID many times unnecessarily. I would take the reassignment inside the If statement and the loop will become
For currentrow = 2 To lastrow
If CustomerID = ws.Cells(currentrow, 1) Then
'find last number that applies
serialno = serialno + 1
're-assign customerID with new serial number
CustomerID = CountryCode & CustomerCode & serialno
End If
Next currentrow
This way CustomerID is only reassigned if and only if serialno changes.
I have an issue with my VBA code, maybe someone can explain where I made a mistake and how can it be fixed.
My goal is to create 7 columns without skipping cells.
I have 7 text boxes but not all of them has to be filled every time data is entered.
At the moment when data is added only in Name text box it creates new row but when only surname is added it skips first empty lines and enters diagonally under Name entry(as in attachment) Excel img
Also there is a mistake when I want to add entry in other text boxes, entered data is just moved around.
Private Sub CommandButton1_Click()
Dim LR As Long
LR = Cells(Rows.Count, 1).End(xlUp).Row + 1
Cells(LR, 1).Value = Name.Value
Cells(LR, 2).Value = Surname.Value
Cells(LR, 3).Value = Address.Value
Cells(LR, 4).Value = Phone.Value
Cells(LR, 5).Value = City.Value
Cells(LR, 6).Value = Car.Value
Cells(LR, 7).Value = Job.Value
Name.Value = ""
Surname.Value = ""
Address.Value = ""
Phone.Value = ""
City.Value = ""
Car.Value = ""
Job.Value = ""
End Sub
You are always looking for the last row in column A, thats why it adds the surname one row below the last row of column A. If you want to know the last row of another column, you need to change the 1 after Rows.Count into the corresponding number. You can also do this in one line, have a gander:
Private Sub CommandButton1_Click()
Cells(Cells(Rows.Count, 1).End(xlUp).Row + 1, 1).Value = Name.Value
Cells(Cells(Rows.Count, 2).End(xlUp).Row + 1, 2).Value = Surname.Value
Cells(Cells(Rows.Count, 3).End(xlUp).Row + 1, 3).Value = Address.Value
Cells(Cells(Rows.Count, 4).End(xlUp).Row + 1, 4).Value = Phone.Value
Cells(Cells(Rows.Count, 5).End(xlUp).Row + 1, 5).Value = City.Value
Cells(Cells(Rows.Count, 6).End(xlUp).Row + 1, 6).Value = Car.Value
Cells(Cells(Rows.Count, 7).End(xlUp).Row + 1, 7).Value = Job.Value
Name.Value = ""
Surname.Value = ""
Address.Value = ""
Phone.Value = ""
City.Value = ""
Car.Value = ""
Job.Value = ""
End Sub
I am getting all the time error 381.. What is there wrong? If i use only 1 column it works, if i add 2nd and more it stops working.
I try to populate my rows which compile with "if statement".
it stops each time to work at 2nd column.
UserForm + some Data:
https://drive.google.com/open?id=1hfCAu2m7C4kISSPJSvyjWc-TvxBr-fOO
2nd Version of code:
Sub PopulateList2()
Dim rngName As Range
Dim ws As Worksheet
Dim i As Integer
Dim LastRow As Long
Set ws = E1G
With ListBoxAbg
.Clear
.ColumnCount = 2
LastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).row
For i = 1 To LastRow
If ws.Cells(i, 6).Value < Now() _
And ws.Cells(i, 6).Value <> vbNullString Then
.AddItem
.List(i - 1, 0) = ws.Cells(i, 1).Value
.List(i - 1, 1) = ws.Cells(i, 3).Value
End If
Next i
End With
End Sub
....
Sub PopulateList2()
Dim rngName As Range
Dim ws As Worksheet
Dim i As Integer
Dim LastRow As Long
Set ws = E1G
AbgeListField.Clear
AbgeListField.ColumnCount = 7
LastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).row
For i = 1 To LastRow
If ws.Cells(i, 6).Value < Now() _
And ws.Cells(i, 6).Value <> vbNullString Then
AbgeListField.AddItem ws.Cells(i, 1).Value
AbgeListField.List(i - 1, 1) = ws.Cells(i, 2).Value
AbgeListField.List(i - 1, 2) = ws.Cells(i, 3).Value
AbgeListField.List(i - 1, 3) = ws.Cells(i, 4).Value
AbgeListField.List(i - 1, 4) = ws.Cells(i, 5).Value
AbgeListField.List(i - 1, 5) = ws.Cells(i, 6).Value
AbgeListField.List(i - 1, 6) = ws.Cells(i, 7).Value
End If
Next i
End Sub
i found the answer in that post:
https://social.msdn.microsoft.com/Forums/office/en-US/f5619db9-be72-41e3-a353-54ebb021f936/runtime-error-381-could-not-set-the-list-property-invalid-property-array-index?forum=exceldev
i added new dim nxtItme As Long. it works perfect now:
Sub PopulateList2()
Dim rngName As Range
Dim ws As Worksheet
Dim i As Integer
Dim LastRow As Long
Dim nxtItem As Long
Set ws = E1G
nxtItem = 0
With ListBoxAbg
.Clear
.ColumnCount = 6
LastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).row
For i = 1 To LastRow
If ws.Cells(i, 6).Value < Now() _
And ws.Cells(i, 6).Value <> vbNullString Then
.AddItem
.List(nxtItem, 0) = ws.Cells(i, 1).Value
.List(nxtItem, 1) = ws.Cells(i, 3).Value
.List(nxtItem, 2) = ws.Cells(i, 4).Value
.List(nxtItem, 3) = ws.Cells(i, 5).Value
.List(nxtItem, 4) = ws.Cells(i, 6).Value
nxtItem = nxtItem + 1
End If
Next i
End With
End Sub
I'm trying to find all rows in a single column with the same value. The program should delete all rows that occur multiple times, apart from one of the columns, which should contract all statements from the deleted rows. This is what I have so far, but I'm getting a loop error:
Sub tester()
Sheets("Sheet1").Select
Dim one As Integer
one = 2
Dim log As Integer
log = 2
Dim compare As Integer
compare = one + 1
Dim ws As String
ws = "Sheet1"
Dim ender As String
ender = "Sheet4"
Dim counter As Integer
counter = 0
Dim lastrow As Integer
lastrow = Cells(Rows.Count, 1).End(xlUp).row
For log = 2 To lastrow - 1
one = log + counter
compare = one + 1
If Worksheets(ws).Cells(one, 1).Value = Worksheets(ws).Cells(compare,1).Value And Worksheets(ws).Cells(one, 7).Value = Worksheets(ws).Cells(compare, 7).Value Then
Do While Worksheets(ws).Cells(one, 1).Value = Worksheets(ws).Cells(compare, 1).Value And Worksheets(ws).Cells(one, 7).Value = Worksheets(ws).Cells(compare, 7).Value
If compare = one + 1 Then
Worksheets(ender).Cells(log, 1).Value = Worksheets(ws).Cells(one, 1).Value
Worksheets(ender).Cells(log, 4).Value = Worksheets(ws).Cells(one, 4).Value
Worksheets(ender).Cells(log, 2).Value = Worksheets(ws).Cells(one, 2).Value
Worksheets(ender).Cells(log, 7).Value = Worksheets(ws).Cells(one, 7).Value
End If
Worksheets(ender).Cells(log, 4).Value = Worksheets(ender).Cells(log, 4).Value & "; " & Worksheets(ws).Cells(compare, 4).Value
compare = compare + 1
counter = counter + 1
Loop
ElseIf Worksheets(ws).Cells(one, 1).Value <> Worksheets(ws).Cells(compare, 1).Value Then
Worksheets(ender).Cells(one - counter, 1).Value = Worksheets(ws).Cells(one, 1).Value
Worksheets(ender).Cells(one - counter, 2).Value = Worksheets(ws).Cells(one, 2).Value
Worksheets(ender).Cells(one - counter, 3).Value = Worksheets(ws).Cells(one, 3).Value
Worksheets(ender).Cells(one - counter, 4).Value = Worksheets(ws).Cells(one, 4).Value
Worksheets(ender).Cells(one - counter, 5).Value = Worksheets(ws).Cells(one, 5).Value
Worksheets(ender).Cells(one - counter, 7).Value = Worksheets(ws).Cells(one, 7).Value
End If
Next log
Sheets("Sheet4").Select
End Sub
Original Data
Desired output