I have an userform and i want to add to some cells data, every time i complete the textboxes with new data. I tried a for but it won't pass the first row.
Dim i As Integer
For i = 19 To 33
Cells(i, 4) = TextBox1.Value
Cells(i, 5) = TextBox2.Value
Cells(i, 6) = TextBox3.Value
Cells(i, 7) = TextBox4.Value
Cells(i, 8) = TextBox5.Value
TextBox1.Value = ""
TextBox2.Value = ""
TextBox3.Value = ""
TextBox4.Value = ""
TextBox5.Value = ""
Next i
End Sub
This is part of the form im making:
If i use the coded provided by Variatus, it inserts the data in cells that are not in the range i need. I tried it before, but it happened to me also. Thats why i was trying a for and a loop or maybe a do/while to see the way around those cells range.
(The example i'm showing, is to insert into column D / row 19, the first TextBox1 value)
I'm not 100% I understand what you're trying to achieve, but if you are looking to simply add do the next row of data in column "D" you can use the below.
The function LastRow I have included will determine the last row that contains data in the specified sheet in the specified column - adding 1 to that figure in the calling subroutine will just continuously add data to the next available line. Hope this helps.
Private Sub CommandButton1_Click()
Dim i As Integer
i = LastRow("Sheet1", "D") + 1
Cells(i, 4) = TextBox1.Value
Cells(i, 5) = TextBox2.Value
Cells(i, 6) = TextBox3.Value
Cells(i, 7) = TextBox4.Value
Cells(i, 8) = TextBox5.Value
TextBox1.Value = ""
TextBox2.Value = ""
TextBox3.Value = ""
TextBox4.Value = ""
TextBox5.Value = ""
End Sub
Function LastRow(wsheet As String, col As String) As Long
Dim ws As Worksheet
Set ws = ActiveWorkbook.Sheets(wsheet)
LastRow = ws.Cells(Rows.Count, col).End(xlUp).Row
End Function
The code below will do what you want. Each time it will write the contents of your 5 text boxes to a new row in the worksheet and then delete whatever was in the text boxes. If you want control over the number of times this action is repeated you need to create another procedure for that purpose.
Sub CommandButton1_Click()
Dim Rt As Long ' row to write to
With Worksheets("Sheet1") ' change point at the correct tab
' find the last used row in columns(4) and add 1
Rt = .Cells(.Rows.Count, 4).End(xlUp).Row + 1
Cells(Rt, 4) = TextBox1.Value
Cells(Rt, 5) = TextBox2.Value
Cells(Rt, 6) = TextBox3.Value
Cells(Rt, 7) = TextBox4.Value
Cells(Rt, 8) = TextBox5.Value
End With
TextBox1.Value = ""
TextBox2.Value = ""
TextBox3.Value = ""
TextBox4.Value = ""
TextBox5.Value = ""
End Sub
The same code can be written somewhat more efficiently using the syntax given below. There is no difference in the functionality. E&EO because I didn't test.)
Sub CommandButton1_Click()
Dim Target As Range ' first cell to write to
Dim i As Long ' loop counter: offset
With Worksheets("Sheet1") ' change point at the correct tab
' find the last used row in columns(4) and add 1
Set Target = .Cells(.Rows.Count, 4).End(xlUp)
End With
For i = 1 To 5
With Me.Controls("TextBox" & i)
Target.Offset(, i + 3).Value = .Value
.Value = ""
End With
Next i
End Sub
Related
I am creating an Excel userform in which users can add, search, and update records. I was able to create a button command that searches the database (a single sheet in my workbook) and populates a listbox with the search results. Because my database has more than 10 columns which I wanted to be visible in the listbox, I used an array to populate the listbox rather than AddItem which limited me to 10 or fewer columns. (the search code is below)
Private Sub Search_Click()
''''''''''''Validation
If Trim(SearchTextBox.Value) = "" And Me.Visible Then
MsgBox "Please enter a search value.", vbCritical, "Error"
Exit Sub
End If
ReDim arrs(0 To 17, 1 To 1)
With Worksheets("Sheet1")
ListBox.Clear
ListBox.ColumnCount = 18
ListBox.ColumnHeads = True
ListBox.Font.Size = 10
ListBox.ColumnWidths = "80,80,150,130,90,90,80,80,80,80,80,60,70,150,150,150,150,180"
If .FilterMode Then .ShowAllData
Set k = .Range("K2:K" & Cells(Rows.Count, "K").End(xlUp).Row).Find(What:="*" & SearchTextBox.Text & "*", LookIn:=xlValues, lookat:=xlWhole)
If Not k Is Nothing Then
adrs = k.Address
Do
M = M + 1
ReDim Preserve arrs(0 To 17, 1 To M)
For j = 0 To 17
arrs(j, M) = .Cells(k.Row, j + 1).Value
Next j
Set k = .Range("K2:K" & Cells(Rows.Count, "K").End(xlUp).Row).FindNext(k)
Loop While Not k Is Nothing And k.Address <> adrs
ListBox.Column = arrs
Else
' If you get here, no matches were found
MsgBox "No matches were found based on the search criteria.", vbInformation
End If
End With
End Sub
I also added code so that when I double click on a record in the listbox, it populates the corresponding textbox in the userform.
Private Sub ListBox_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
TextBox1.Text = ListBox.Column(0)
If TextBox1.Text = ListBox.Column(0) Then
TextBox1.Text = ListBox.Column(0)
TextBox2.Text = ListBox.Column(1)
TextBox3.Text = ListBox.Column(2)
TextBox4.Text = ListBox.Column(3)
TextBox5.Text = ListBox.Column(4)
TextBox6.Text = ListBox.Column(5)
TextBox7.Text = ListBox.Column(6)
TextBox8.Text = ListBox.Column(7)
TextBox9.Text = ListBox.Column(8)
TextBox10.Text = ListBox.Column(9)
TextBox11.Text = ListBox.Column(10)
TextBox12.Text = ListBox.Column(11)
TextBox13.Text = ListBox.Column(12)
TextBox14.Text = ListBox.Column(13)
TextBox15.Text = ListBox.Column(14)
TextBox16.Text = ListBox.Column(15)
TextBox17.Text = ListBox.Column(16)
TextBox18.Text = ListBox.Column(17)
End If
End Sub
After double clicking on a search result from the listbox, I want users to be able to edit any information in those textboxes and click a command button to update that entry/record in the database itself. However, I am having some problems with creating this function. I used the following code, and although it doesn't return an error message, it doesn't change the entry in the database.
Dim X As Long
Dim Y As Long
X = Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
For Y = 2 To X
If Sheets("Sheet1").Cells(Y, 11).Value = SearchTextBox.Text Then
Sheets("Sheet1").Cells(Y, 1).Value = TextBox1
Sheets("Sheet1").Cells(Y, 2).Value = TextBox2
Sheets("Sheet1").Cells(Y, 3).Value = TextBox3
Sheets("Sheet1").Cells(Y, 4).Value = TextBox4
Sheets("Sheet1").Cells(Y, 5).Value = TextBox5
Sheets("Sheet1").Cells(Y, 6).Value = TextBox6
Sheets("Sheet1").Cells(Y, 7).Value = TextBox7
Sheets("Sheet1").Cells(Y, 8).Value = TextBox8
Sheets("Sheet1").Cells(Y, 9).Value = TextBox9
Sheets("Sheet1").Cells(Y, 10).Value = TextBox10
Sheets("Sheet1").Cells(Y, 11).Value = TextBox11
Sheets("Sheet1").Cells(Y, 12).Value = TextBox12
Sheets("Sheet1").Cells(Y, 13).Value = TextBox13
Sheets("Sheet1").Cells(Y, 14).Value = TextBox14
Sheets("Sheet1").Cells(Y, 15).Value = TextBox15
Sheets("Sheet1").Cells(Y, 16).Value = TextBox16
Sheets("Sheet1").Cells(Y, 17).Value = TextBox17
Sheets("Sheet1").Cells(Y, 18).Value = TextBox18
End If
Next Y
Additionally, the term that I am searching with is not unique, so there are multiple records/rows in the database with the same search term. How can I create this code in a way that I when I click on the update button, information from the userform (which has been populated by doubleclicking the record in the listbox) is updated in the excel sheet but not for all records with the same search term?
Thank you so much for any help!
Add a Label to your UserForm to hold the row number from where the text box values came. Use the first column (width zero so hidden) of the listbox to hold the row number of the filtered rows. Set the label to column 0 of the double clicked row.
Option Explicit
Private Sub Update_Click()
Dim r As Long, n As Long
' record showing
r = Val(Label1.Caption)
If r < 1 Then
Exit Sub
End If
With Sheets("Sheet1")
For n = 1 To 18
.Cells(r, n).Value2 = Me.Controls("TextBox" & n)
Next
End With
End Sub
Private Sub ListBox_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Dim n As Long
With ListBox
For n = 1 To ListBox.ColumnCount - 1
Debug.Print n, .Column(n)
Me.Controls("TextBox" & n).Text = .Column(n)
Next
Label1.Caption = .Column(0)
End With
End Sub
Private Sub Search_Click()
Const COLS = 18
Dim s
s = Trim(SearchTextBox.Value)
If s = "" And Me.Visible Then
MsgBox "Please enter a search value.", vbCritical, "Error"
Exit Sub
Else
s = "*" & s & "*"
End If
Dim rngFnd As Range, rngSearch As Range, first As String
Dim arr, lastrow As Long, i As Long, j As Long
' search sheet
With Worksheets("Sheet1")
If .FilterMode Then .ShowAllData
lastrow = .Cells(.Rows.Count, "K").End(xlUp).Row
Set rngSearch = .Range("K1:K" & lastrow)
i = WorksheetFunction.CountIf(rngSearch, s)
If i > 0 Then
ReDim arr(0 To COLS, 1 To i)
Set rngFnd = rngSearch.Find(What:=s, LookIn:=xlValues, lookat:=xlWhole)
If Not rngFnd Is Nothing Then
i = 0
first = rngFnd.Address
Do
i = i + 1
arr(0, i) = rngFnd.Row
For j = 1 To COLS
arr(j, i) = .Cells(rngFnd.Row, j).Value
Next j
Set rngFnd = rngSearch.FindNext(rngFnd)
Loop While rngFnd.Address <> first
End If
Else
'If you get here, no matches were found
MsgBox "No matches were found based on the search criteria. " & s, vbExclamation
Exit Sub
End If
End With
' format listbox
With ListBox
.Clear
.ColumnCount = COLS + 1
.ColumnHeads = True
.Font.Size = 10
.ColumnWidths = "0,80,80,150,130,90,90,80,80,80,80,80,60,70,150,150,150,150,180"
.Column = arr
End With
End Sub
Sub a()
Dim i As Integer
For i = 1 To 8
If Cells(i, 1).Value = "M" Then
Cells(i, 2).Value = ""
End If
Next i
End Sub
You need to include the sheet information along with the cells.
Example: Sheet1.Cells(i,1).Value or Worksheets("Sheet name").Cells(i,1).Value
I have a Sub NewRecord() to create new record and a Sub CB_No_Change() to recall existing record by number to be displayed on the user form. For Sub NewRecord(), I write the code so that some default values are put into the excel sheet in the next empty row then this new record is recalled by Sub CB_No_Change() to be displayed on the user form and can be edited. The Sub CB_No_Change() is working fine on its own, but the Sub NewRecord() usually crashes when being run (the excel application does not respond and automatically reboots). I suspect there may be a loop between this 2 subs? Any ideas?
Private Sub NewRecord()
Dim LastRow As Integer
Dim emptyRow As Integer
LastRow = WorksheetFunction.CountA(Range("$A:$A"))
emptyRow = LastRow + 1
Cells(emptyRow, 1) = "xxx"
Cells(emptyRow, 2) = "xxx"
Cells(emptyRow, 3) = "xxx"
Cells(emptyRow, 4) = "xxx"
Cells(emptyRow, 5) = "xxx"
Cells(emptyRow, 6) = "xxx"
Cells(emptyRow, 7) = "xxx"
Cells(emptyRow, 8) = "xxx"
Cells(emptyRow, 9) = "xxx"
Cells(emptyRow, 10) = "xxx"
Cells(emptyRow, 11) = "xxx"
Cells(emptyRow, 12) = "xxx"
Cells(emptyRow, 13) = "xxx"
Cells(emptyRow, 14) = "xxx"
Cells(emptyRow, 15) = "xxx"
Cells(emptyRow, 16) = "xxx"
Cells(emptyRow, 17) = "xxx"
Me.CB_No = LastRow
Me.TB_RecdDate.SetFocus
End sub
Private Sub CB_No_Change()
Dim FindNo As String
Dim r As Integer
Dim TrgtNo As Range
If Me.CB_No <> "" Then
FindNo = Me.CB_No.Value
Set TrgtNo = Worksheets("One").Range("$A:$A").Find(FindNo, SearchOrder:=xlRows, SearchDirection:=xlPrevious, Lookat:=xlWhole)
If Not TrgtNo Is Nothing Then
r = Worksheets("One").Range("$A:$A").Find(FindNo, SearchOrder:=xlRows, SearchDirection:=xlPrevious, Lookat:=xlWhole).Row
CB = Cells(r, 1)
TB = Cells(r, 2)
Me.TB = Format(Me.TB, "yyyy-mm-dd")
TB = Cells(r, 3)
Me.TB = Format(Me.TB, "yyyy-mm-dd")
TB = Cells(r, 4)
TB = Cells(r, 5)
TB = Cells(r, 6)
TB = Cells(r, 7)
CB = Cells(r, 8)
CB = Cells(r, 9)
CB = Cells(r, 10)
TB = Cells(r, 11)
TB = Cells(r, 12)
TB = Cells(r, 13)
CB = Cells(r, 14)
CB = Cells(r, 15)
CB = Cells(r, 16)
TB = Cells(r, 17)
Else
Exit Sub
End If
Else
Exit Sub
End If
End Sub
Looking at your code, it looks like you are trying to get the row number of the last row in column A, so you can get the row number of the first empty row adding +1 to LastRow.
You are using CountA, a function that just counts non-empty cells in a range.
WorksheetFunction.CountA method (Excel)
This will work only if all your data is continuous. But if your data is like this:
You can see this with an easy code applied to data in the image:
Sub test()
Dim LastRowWithCountA As Long
Dim LastRowNormal As Long
LastRowWithCountA = Application.WorksheetFunction.CountA(Range("A:A"))
LastRowNormal = Range("A" & Rows.Count).End(xlUp).Row
Debug.Print "COUNTA: " & LastRowWithCountA & " VS " & "NORMAL:" & LastRowNormal
End Sub
It will return COUNTA: 15 VS NORMAL:19.
So the best option to get the last non empty row in a column is Range("A" & Rows.Count).End(xlUp).Row
About your error, replaceIntegers with Long. Integers got a lower limit. I recommend you to read all data types admited.
Data type summary
Highlighted is the this photo Worksheet are the data with the same identification but has distinct data in one of the column. In Code below i was able to search one of the data in the same identification but it will not show in my form. UserForm. What I wanted needed is to show the 2 different datas with the same RF Number when I click the search button.
VBA Code
Private Sub CommandButton1_Click()
Dim x As Long
Dim y As Long
x = Sheets("ONGOING").Range("A" & Rows.Count).End(xlUp).Row
For y = 1 To x
If Sheets("ONGOING").Cells(y, 1).Text = TextBox1.Value Then
TextBox1.Text = Sheets("ONGOING").Cells(y, 1)
TextBox2.Text = Sheets("ONGOING").Cells(y, 3 )
TextBox3.Text = Sheets("ONGOING").Cells(y, 5)
TextBox4.Text = Sheets("ONGOING").Cells(y, 8)
TextBox5.Text = Sheets("ONGOING").Cells(y, 9)
TextBox6.Text = Sheets("ONGOING").Cells(y, 6)
TextBox7.Text = Sheets("ONGOING").Cells(y, 7)
ComboBox1.Text = Sheets("ONGOING").Cells(y, 4)
ComboBox2.Text = Sheets("ONGOING").Cells(y, 2)
End If
Next y
End Sub
Here is a fast solution without for loop. It will actually go round on each click - e.g. if you have 3 items for same RF# it will show you 1, 2, 3, 1, 2, 3... and so on on each click.
Private Sub CommandButton1_Click()
'we set the cell from where we start the search as static -
'it keeps its value even after the macro has ended.
Static varFoundCell As Variant
Dim rSource As Range 'declaring ranges just to make it clearer
Dim rTarget As Range
Set rSource = ThisWorkbook.Worksheets("Ongoing").Range("A1").CurrentRegion
'if cell is empty it means the previous search did not give a result - so we start looking from the first cell again.
If IsEmpty(varFoundCell) Then Set varFoundCell = rSource.Cells(1, 1)
'we looking for RF# in the first column of the source range and return the cell where it is found
Set rTarget = rSource.Columns(1).Find(TextBox1.Text, varFoundCell, LookIn:=xlValues)
'if we found it then we assigne the cell it is in as the cell we start our next search from
If Not (rTarget Is Nothing) Then Set varFoundCell = rTarget
'we found the cell, we get its row to take outher data from the source range
TextBox2.Text = rSource(rTarget.Row, 2)
'the rest of controls go here below
End Sub
maybe you needed this:
Private Sub CommandButton1_Click()
Dim x As Long
Dim y As Long
Dim found As Boolean ' add a boolean variable
With Sheets("ONGOING")
x = .Range("A" & .Rows.Count).End(xlUp).Row
For y = 1 To x
If .Cells(y, 1).Text = TextBox1.Value Then
If Not found Then ' if first matching RF
found = True ' mark current RF as already found at least once
TextBox1.Text = .Cells(y, 1)
TextBox2.Text = .Cells(y, 3)
TextBox3.Text = .Cells(y, 5)
TextBox4.Text = .Cells(y, 8)
TextBox5.Text = .Cells(y, 9)
TextBox6.Text = .Cells(y, 6)
TextBox7.Text = .Cells(y, 7)
ComboBox1.Text = .Cells(y, 4)
ComboBox2.Text = .Cells(y, 2)
Else 'otherwise
TextBox3.Text = TextBox3.Text & "," & .Cells(y, 5) 'update items list textbox
End If
End If
Next y
End With
End Sub
I am trying to write a code that will take one cell and then iterate through another column to find a match, once it has found a match it will then match two other cells in that same row and return the value of a 5th and 6th cell. However, it is not working! any suggestions??
Sub rates()
Dim i As Integer
For i = 2 To 2187
If Cells(i, 1).Value = Cells(i, 11).Value Then
If Cells(i, 2).Value = Cells(i, 12).Value Then
Cells(i, 20) = Cells(i, 1).Value
Cells(i, 21) = Cells(i, 11).Value
Cells(i, 22) = Cells(i, 4).Value
Cells(i, 23) = Cells(i, 16).Value
Else
Cells(i, 24) = "No match"
End If
End If
Next i
End Sub
Try fully qualifying your cell objects i.e. sheet1.cells(i,1).value etc or encase within a with statement i.e.
with sheet1
if .cells(i,X) = .cells(i,Y) then
'...etc
end with
I think the default property for a range is "Value" but try putting .Value on to the end of all those Cell lines too... like you have for half of them :)
[EDIT/Addition:]
... failing that, you're not actually searching a whole column at any point: try something like:
Sub rates()
Dim i As Integer
Dim rgSearch As Range
Dim rgMatch As Range
Dim stAddress As String
Dim blMatch As Boolean
With wsSheet
Set rgSearch = .Range(.Cells(x1, y1), .Cells(x2, y2)) ' Replace where appropriate (y = 1 or 11 i guess, x = start and end row)
End With
For i = 2 To 2187
Set rgMatch = rgSearch.Find(wsSheet.Cells(i, y)) ' y = 1 or 11 (opposite of above!)
blMatch = False
If Not rgMatch Is Nothing Then
stAddress = rgMatch.Address
Do Until rgMatch Is Nothing Or rgMatch.Address = stAddress
If rgMatch.Offset(0, y).Value = Cells(i, 12).Value Then
Cells(i, 20) = Cells(i, 1).Value
Cells(i, 21) = Cells(i, 11).Value
Cells(i, 22) = Cells(i, 4).Value
Cells(i, 23) = Cells(i, 16).Value
blMatch = True
Else
End If
Set rgMatch = rgSearch.FindNext(rgMatch)
Loop
End If
If Not blMatch Then
Cells(i, 24) = "No match"
End If
Next i
End Sub
I've made a lot of assumptions in there and there's a few variables you'll have to replace. You could also probably use application.worksheetfunction.match but .find is quicker and more awesome