I'm using a vba UserForm to enter in "Vehicle Reg" and choose "Current Status" from a combobox, which currently adds this data to a new line along with a uniqueID, the username, and the time.
I'd like to create a finite list of Vehicle Reg, and use the UserForm to update the Current Status (1 column to the right) with the new value.
Is there a way I can alter what I have to make this work? I am brand new to vba and have been googling for days!
I have a Submit Button, a Reset Button, and on the main spreadsheet I have a macro button that I have attached the "Show Form".
Here's what I have:
Sub Reset()
Dim iRow As Long
iRow = [Counta(Database!A:A)] 'identifying the last row
With frmForm
.txtID.Value = ""
.cmbStatus.Clear
.cmbStatus.AddItem "Loaded - In"
.cmbStatus.AddItem "Loaded - Out"
.cmbStatus.AddItem "Empty - Parked"
.cmbStatus.AddItem "Empty - On Bay"
.lstDatabase.ColumnCount = 4
.lstDatabase.ColumnHeads = True
If iRow > 1 Then
.lstDatabase.RowSource = "Database!A2:C" & iRow
Else
.lstDatabase.RowSource = "Database!A2:C2"
End If
End With
End Sub
Sub Submit()
Dim sh As Worksheet
Dim iRow As Long
Set sh = ThisWorkbook.Sheets("Database")
iRow = [Counta(Database!A:A)] + 1
With sh
.Cells(iRow, 1) = iRow - 1
.Cells(iRow, 2) = frmForm.txtID.Value
.Cells(iRow, 3) = frmForm.cmbStatus.Value
.Cells(iRow, 4) = Application.UserName
.Cells(iRow, 5) = [Text(Now(), "DD-MM-YYY HH:MM:SS")]
End With
End Sub
Sub Show_Form()
Call Reset
frmForm.Show
End Sub
**And my initialize code:**
Private Sub UserForm_Initialize()
With frmForm
Height = 370
Width = 645
End With
End Sub
Private Sub cmdReset_Click()
Dim msgValue As VbMsgBoxResult
msgValue = MsgBox("Do you want to reset the form?", vbYesNo + vbInformation, "Confirmation")
If msgValue = vbNo Then Exit Sub
Call Reset
End Sub
Private Sub cmdSave_Click()
With Me
If txtID.Value = "" Then
MsgBox "Reg Cannot Be Blank", vbOKOnly + vbCritical + vbDefaultButton1, "Reg Blank"
End If
Exit Sub
End With
Dim msgValue As VbMsgBoxResult
msgValue = MsgBox("Do you want to save?", vbYesNo + vbInformation, "Confirmation")
If msgValue = vbNo Then Exit Sub
Call Submit
Call Reset
Unload Me
End Sub
Private Sub frmForm_Initialize()
Call Reset
End Sub
Thanks!
Use the lstDatabase_Click() event together with the .ListIndex property to load the form items from the sheet. The Reset de-selects the line. Save without a line selected adds a new record, with line selected updates the existing record.
Option Explicit
Sub Show_Form()
frmForm.Show
End Sub
Private Sub cmdReset_Click()
' unselect line lstdatabase
With Me
.txtID.Value = ""
.cmbStatus = ""
.lstDatabase.ListIndex = -1
End With
End Sub
Private Sub UserForm_Initialize()
With Me
.Height = 370
.Width = 645
.txtID.Value = ""
.cmbStatus.Clear
.cmbStatus.AddItem "Loaded - In"
.cmbStatus.AddItem "Loaded - Out"
.cmbStatus.AddItem "Empty - Parked"
.cmbStatus.AddItem "Empty - On Bay"
.lstDatabase.ColumnCount = 4
.lstDatabase.ColumnHeads = True
End With
LoadDatabase
End Sub
Private Sub cmdSave_Click()
If txtID.Value = "" Then
MsgBox "Reg Cannot Be Blank", vbCritical, "Reg Blank"
ElseIf cmbStatus.Value = "" Then
MsgBox "Status Cannot Be Blank", vbCritical, "Status Blank"
ElseIf MsgBox("Do you want to save?", vbYesNo, "Confirmation") = vbYes Then
Call Submit
'Unload Me
End If
End Sub
Sub Submit()
Dim i As Long, r As Long
With lstDatabase
i = .ListIndex
' is line selected
If i >= 0 Then r = .List(i, 0) + 1
End With
' update or add
With Sheets("Database")
' add new find last line
If r = 0 Then
r = 1 + .Cells(.Rows.Count, "A").End(xlUp).Row
.Cells(r, 1) = r - 1
.Cells(r, 2) = frmForm.txtID.Value
End If
' update
.Cells(r, 3) = frmForm.cmbStatus.Value
.Cells(r, 4) = Application.UserName
.Cells(r, 5) = [Text(Now(), "DD-MM-YYY HH:MM:SS")]
End With
End Sub
Private Sub lstDatabase_Click()
Dim i As Long, r As Long
With lstDatabase
i = .ListIndex
If i >= 0 Then
txtID.Value = .List(i, 1)
cmbStatus.Text = .List(i, 2)
End If
End With
End Sub
Sub LoadDatabase()
Dim iRow As Long
With Sheets("Database")
iRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
If iRow < 2 Then iRow = 2
lstDatabase.RowSource = "Database!A2:C" & iRow
End Sub
Related
I am trying to create a front-end form that can be filled out by a user, which will then populate a back-end spreadsheet the user cannot edit. This spreadsheet needs to follow a standard layout that I have already created, and the form will populate predetermined cells (or will create cells following the layout) based on user input from the form. I also need the form to be able to add/repeat questions, as well as duplicate sections in the spreadsheet based on user input requirements ("Do you need to add a section? [Yes/No]" //If [Yes], then duplicate section, repeat questions in form; if [No], then export data to spreadsheet, exit form). The spreadsheet layout consists of sections. The number of sections/cells per section required will vary from user to user, but the type of data will typically remain the same, and therefore should be able to choose the name of the field from a list of some sort (drop down?) However, the user may need to create a custom name for a field. I also need the form to be able to automatically adjust cell sizes based on the amount of text for that value. It is important that this form is printable, and does not separate sections from page to page. Furthermore, each "Notes" field will vary in size, and should be automatically resized to only show the existing text, plus one blank line for hand-written notes. I would also like the form to prompt the user to indicate whether a field is needed (some fields will be permanent, and the user will not be prompted about these fields). If the field is not needed, I need the form to exclude it from the final output.
I am open to suggestions on how to design this project differently than I have already (for example, using alternate programs/software/coding languages).
So far, however, I have created a user form in Excel that collects data and inputs it into a spreadsheet, which can then be exported to a PDF report using a set format/layout on another sheet of the workbook. The layout consists of a "Header" section and an "Item" section. In the form, the user can input a single job number and multiple item numbers, and when they export the report, the code prints the job number in the provided layout for the header, and then loops through the item numbers and copies and populates the item section for as many items as the user has provided. In the exported PDF, however, the item section gets split between pages, regardless of page orientation (landscape orientation is preferred). How do I prevent the "Item" section from being broken up between pages?
Option Explicit
Dim ctl As Control
Dim rCell As Range
Dim img As Picture
Dim newrow As ListRow
Dim tbl1 As ListObject
Dim msgValue As VbMsgBoxResult
Dim ary As Variant, aryx As Variant
Dim ws2 As Worksheet, ws1 As Worksheet
Dim s As String, FilePath As String, user As String, pFilename As String, part As String
Dim x As Long, sc As Long, j As Long, ctr As Long, rctr As Long, tbl1row As Long, r As Long, t As Long, items As Long, y As Long, ctrx As Long
Private Sub cmdCLEAR_Click()
MsgBox ("This action only clears the form NOT the record" & vbCrLf & "Ready for adding NEW entry."), vbOKOnly, "Clear Form "
CLEARFORM
Me.cmdADD.Enabled = True
Me.TextBox6.SetFocus
End Sub
Sub CLEARFORM()
For Each ctl In Me.Controls
Select Case TypeName(ctl)
Case "TextBox"
ctl.Text = ""
Case "ComboBox"
ctl.ListIndex = -1
ctl.Value = ""
End Select
Next ctl
Me.Image1.Picture = LoadPicture("") '*********clears picture******
End Sub
Private Sub cmdADD_Click()
For x = 1 To 35
If Controls("TextBox" & x).Text = "" Then
MsgBox "Data field missing", vbCritical, "Data missing"
Exit Sub
End If
Next x
msgValue = MsgBox("Do want to add another item?", vbYesNo + vbQuestion, "Next Item ?")
If msgValue = vbYes Then
SAVEDATANEXT
For x = 16 To 35
Me.Controls("TextBox" & x).Text = ""
Next x
Me.TextBox6.SetFocus
Exit Sub
End If
SAVEDATA
LOADLIST
LOADCOMBO1
End Sub
Sub SAVEDATANEXT()
Set newrow = tbl1.ListRows.Add
With newrow
For x = 1 To 35
.Range(x) = Me.Controls("TextBox" & x).Text '***************textbox35 contains picture filepath ***********
Next x
.Range(36) = tbl1.ListRows.Count '*********this is important row counter saves the need for search routines***********
End With
End Sub
Sub SAVEDATA()
Set newrow = tbl1.ListRows.Add
With newrow
For x = 1 To 35
.Range(x) = Me.Controls("TextBox" & x).Text '***************textbox35 contains picture filepath ***********
Next x
.Range(36) = tbl1.ListRows.Count '*********this is important row counter saves the need for search routines***********
End With
CLEARFORM
LOADLIST
End Sub
Sub LOADLIST()
Set ws2 = Sheet2
Set tbl1 = ws2.ListObjects("Table1")
With tbl1
If .DataBodyRange.Cells(1, 1) = vbNullString Then Exit Sub
ary = .DataBodyRange
End With
Me.ListBox1.List = ary
End Sub
Private Sub cmdPRINT_Click()
If Me.ComboBox1.Value = vbNullString Then
MsgBox "A PDF cannot be created because no Part # selected.", , "No Part# selected."
Exit Sub
End If
With Sheet3
.Range("A28:O10000").Clear
.Range("D2:D10").Value = ""
.Range("J2:J8").Value = ""
.Range("B17:N17").Value = ""
.Range("B19:N19").Value = ""
.Range("B21:N21").Value = ""
.Range("D23").Value = ""
For Each img In Sheet3.Pictures: img.Delete: Next img '**********clears pictures prior to building new PDF********
ctr = 28
For x = 1 To items - 2
.Range("A15:O26").Copy .Range("A" & ctr)
ctr = ctr + 13
Next x
For y = 2 To 8
.Range("D" & y).Value = Me.ListBox1.List(0, y - 2)
.Range("J" & y).Value = Me.ListBox1.List(0, y - 2 + 7)
.Range("D10").Value = Me.ListBox1.List(0, 14)
Next y
ctr = 0
ctrx = 0
For x = 1 To items - 1
.Cells(17 + ctr, 2).Value = Me.ListBox1.List(ctrx, 15)
.Cells(17 + ctr, 4).Value = Me.ListBox1.List(ctrx, 16)
.Cells(17 + ctr, 6).Value = Me.ListBox1.List(ctrx, 17)
.Cells(17 + ctr, 8).Value = Me.ListBox1.List(ctrx, 18)
.Cells(17 + ctr, 10).Value = Me.ListBox1.List(ctrx, 19)
.Cells(17 + ctr, 12).Value = Me.ListBox1.List(ctrx, 20)
.Cells(17 + ctr, 14).Value = Me.ListBox1.List(ctrx, 21)
.Cells(19 + ctr, 2).Value = Me.ListBox1.List(ctrx, 22)
.Cells(19 + ctr, 4).Value = Me.ListBox1.List(ctrx, 23)
.Cells(19 + ctr, 6).Value = Me.ListBox1.List(ctrx, 24)
.Cells(19 + ctr, 8).Value = Me.ListBox1.List(ctrx, 25)
.Cells(19 + ctr, 10).Value = Me.ListBox1.List(ctrx, 26)
.Cells(19 + ctr, 12).Value = Me.ListBox1.List(ctrx, 27)
.Cells(21 + ctr, 2).Value = Me.ListBox1.List(ctrx, 28)
.Cells(21 + ctr, 6).Value = Me.ListBox1.List(ctrx, 29)
.Cells(21 + ctr, 8).Value = Me.ListBox1.List(ctrx, 30)
.Cells(21 + ctr, 12).Value = Me.ListBox1.List(ctrx, 31)
.Cells(21 + ctr, 14).Value = Me.ListBox1.List(ctrx, 32)
.Cells(23 + ctr, 4).Value = Me.ListBox1.List(ctrx, 33)
'**************************************inserting picture into PDF loader*****************
pFilename = Me.ListBox1.List(ctrx, 34)
If pFilename = "" Then GoTo Err:
Set img = .Pictures.Insert(pFilename)
With img
.Left = Sheet3.Cells(23 + ctr, 14).Left
.Top = Sheet3.Cells(23 + ctr, 14).Top
.Width = 16
.Height = 44.25
.Placement = 1
.PrintObject = True
End With
Err:
'***************************************************************************************
ctrx = ctrx + 1
ctr = ctr + 13
Next x
End With
user = Environ("Username")
FilePath = "C:\Users\" & user & "\Desktop\"
ThisWorkbook.Worksheets("Sheet3").Select
part = Sheet3.Cells(2, 4)
Application.ScreenUpdating = True
'*****************set print area and orientaton********************
Application.PrintCommunication = False
With ActiveSheet.PageSetup
.Orientation = xlLandscape
.PrintArea = Sheet3.Range(Sheet3.Cells(1, 1), Sheet3.Cells(ctr, 15))
.Zoom = False
.FitToPagesTall = False
.FitToPagesWide = 1
INSERTBREAK
End With
Application.PrintCommunication = True
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=FilePath & "\Part# " & part, OpenAfterPublish:=False, IgnorePrintAreas:=False
'*********************************************************************
Application.ScreenUpdating = True
MsgBox "Data has been exported to PDF on Desktop."
With Sheet3
.Range("A28:O10000").Clear
.Range("D2:D10").Value = ""
.Range("J2:J8").Value = ""
.Range("B17:N17").Value = ""
.Range("B19:N19").Value = ""
.Range("B21:N21").Value = ""
.Range("D23").Value = ""
For Each img In Sheet3.Pictures: img.Delete: Next img '**********clears pictures ready to build new PDF********
End With
End Sub
'********************************open file dialog box to get picture location******************
Private Sub cmdGETPHOTO_Click()
On Error Resume Next
pFilename = Application.GetOpenFilename(FileFilter:="Jpg Files (*.jpg), *.jpg", Title:="SELECT TOOL PHOTO")
Me.Image1.Picture = LoadPicture(pFilename)
Me.TextBox35.Text = pFilename
End Sub
Private Sub CommandButton1_Click()
Unload Me
End Sub
Private Sub Frame1_Click()
End Sub
Private Sub Frame2_Click()
End Sub
Private Sub ListBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single)
If Me.ListBox1.ListIndex = -1 Then Exit Sub
If Me.ListBox1.ListIndex > -1 Then sc = Me.ListBox1.ListIndex
With Me.ListBox1
For x = 1 To 35
Me.Controls("TextBox" & x).Value = .List(sc, x - 1)
Next x
tbl1row = .List(sc, 35)
End With
On Error GoTo Err
Me.Image1.Picture = LoadPicture(Me.TextBox35.Text) 'retrieves picture file location************
Exit Sub
Err: Me.Image1.Picture = LoadPicture("")
End Sub
Private Sub cmdDELETE_Click()
If Me.ListBox1.ListIndex < 0 Then
MsgBox "No Record selected", , "Errors"
Exit Sub
End If
msgValue = MsgBox("ARE YOU CERTAIN YOU WISH TO REMOVE RECORD?", vbCritical + vbYesNo + vbDefaultButton2, "Remove Record")
If msgValue = vbNo Then
CLEARFORM
Exit Sub
End If
tbl1.ListRows(tbl1row).Delete
CLEARFORM
LOADLIST
LOADCOMBO1
MsgBox ("RECORD REMOVED"), vbOKOnly + vbInformation, "Record Removed"
End Sub
Private Sub cmdUPDATE_Click()
If Me.ListBox1.ListIndex < 0 Then
MsgBox "No Record selected", , "Errors"
Exit Sub
End If
With tbl1
For x = 1 To 35
.Range(tbl1row + 1, x) = Me.Controls("TextBox" & x).Text '*********textbox35 contains picture filepath **********
Next x
End With
CLEARFORM
LOADLIST
LOADCOMBO1
End Sub
Private Sub ComboBox1_Change()
With tbl1
r = .ListRows.Count
For t = r To 1 Step -1
.DataBodyRange.Cells(t, 36) = t '******loads range with rowctr prior to spliting with 'FILTER' ***********
Next t
End With
FILTER
items = Me.ListBox1.ListCount
End Sub
Sub FILTER()
ary = tbl1.DataBodyRange
rctr = 1
For j = 1 To UBound(ary)
If ary(j, 1) = Me.ComboBox1.Text Then
rctr = rctr + 1
End If
Next j
ReDim aryx(1 To rctr, 1 To 36)
ctr = 1
For j = 1 To UBound(ary)
If ary(j, 1) = Me.ComboBox1.Text Then
For x = 1 To 36
aryx(ctr, x) = ary(j, x)
Next x
ctr = ctr + 1
End If
Next j
Me.ListBox1.List = aryx
End Sub
Sub LOADCOMBO1()
Set ws2 = Sheet2
Set tbl1 = ws2.ListObjects("Table1")
With tbl1
If .DataBodyRange.Cells(1, 1) = vbNullString Then Exit Sub
ary = .DataBodyRange
End With
Me.ComboBox1.Clear
With CreateObject("Scripting.Dictionary")
For Each rCell In tbl1.ListColumns(1).DataBodyRange
If Not .Exists(rCell.Value) And rCell.Value <> vbNullString Then .Add rCell.Value, Nothing
Next rCell
Me.ComboBox1.List = .keys
.RemoveAll
End With
End Sub
Private Sub UserForm_Initialize()
Set ws2 = Sheet2
Set tbl1 = ws2.ListObjects("Table1")
Me.ListBox1.ColumnCount = 36
s = ""
For x = 1 To 36
s = s & 50 & ";"
Next x
Me.ListBox1.ColumnWidths = s
For x = 1 To 35
Me.Controls("Label" & x).Caption = tbl1.HeaderRowRange(x)
Next x
Me.cmdADD.Enabled = True
Me.TextBox35.Enabled = False
LOADLIST
LOADCOMBO1
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
'************ensures workbook is saved if accidently closed**************
If CloseMode = vbFormControlMenu Then
Cancel = False
ThisWorkbook.Save
Unload Me
End If
End Sub
I have tried using various forms of the PageBreak method. I have also tried setting the page layout in various ways, but nothing has worked. I even tried grouping the cells in the "Item" section. I am at a total loss.
I am completely new in this and got stuck on something that sounds like a simple thing.
I created simple user form, where assemblers will enter one of the items as a search criteria. The listbox is then populated with all results from original spreadsheet showing the location of that part. Assembler will then select one item that they need to pick and click the button "pick".
What that will do is enter the date in "PickDate" in spreadsheet. And that is where I am stuck.
My thinking was to select the row in the spreadsheet identical to the selected row in listbox, and then create address of the cell using that row and column. But it doesn't work. Tried several things that I could find on internet and nothing works. At one point I had date being entered in correct column, but not correct row. Unfortunately, cannot remember what that code was.
Any help would be appreciated.
Thanks a lot. userform spreadsheet
Private Sub PickBtn_Click()
Dim i As Integer
For i = 1 To Range("A10000").End(xlUp).Row
If Cells(i, 2) = Results.List(Results.ListIndex) Then
Rows(i).Select
.Range(Selection, 7).Value = Date
End If
Next i
End Sub
Entry form
Private Sub CancelJob_Click()
'Close EntryForm form
Unload EntryForm
'Show InitialForm form
InitialForm.Show
End Sub
Private Sub UserForm_Initialize()
'Empty all fields
JobBox.Value = ""
Customer.Value = ""
Location.Value = ""
Rack.Value = ""
'Fill combo box with product types
With ProductCombo
.AddItem "Channel Letter Faces"
.AddItem "Channel Letter Backers"
.AddItem "Routed Aluminum Panels"
.AddItem "Routed ACM Panels"
End With
'Set focus on Work order TextBox
JobBox.SetFocus
End Sub
Private Sub SubmitJob_Click()
'Make fields mandatory
If JobBox.Value = "" Or ProductCombo.Value = "" Or Rack.Value = "" Then
If MsgBox("Cannot submit. Please fill the mandatory fields.",
vbQuestion + vbOKOnly) <> vbOKOnly Then
Exit Sub
End If
End If
'Start transfering process
Dim emptyRow As Long
'Make Sheet1 active
Sheet1.Activate
'Determine emptyRow
emptyRow = WorksheetFunction.CountA(Range("A:A")) + 1
'Transfer information to the table
Cells(emptyRow, 1).Value = Date 'Auto populate 1st column with submission date
Cells(emptyRow, 2).Value = JobBox.Value
Cells(emptyRow, 3).Value = Customer.Value
Cells(emptyRow, 4).Value = Location.Value
Cells(emptyRow, 5).Value = ProductCombo.Value
Cells(emptyRow, 6).Value = Rack.Value
'Save workbook after transfer of data
ActiveWorkbook.Save
'Close EntryForm
Unload Me
'Quit application so that others can use it
'Application.Quit
End Sub
This is complete code for this search part of the userform that I cannot
figure out (I was playing with the code for "submit" button that I am stuck). Maybe it will help for troubleshooting:
Private Sub ClearForm(Except As String)
' Clears the list box and text boxes EXCEPT the text box
' currently having data entered into it
Select Case Except
Case "Job"
FormEvents = False
Customer.Value = ""
Location.Value = ""
Results.Clear
FormEvents = True
Case "Customer"
FormEvents = False
Job.Value = ""
Location.Value = ""
Results.Clear
FormEvents = True
Case "Location"
FormEvents = False
Job.Value = ""
Customer.Value = ""
Results.Clear
FormEvents = True
Case Else
FormEvents = False
Job.Value = ""
Customer.Value = ""
Location.Value = ""
Results.Clear
FormEvents = True
End Select
End Sub
Private Sub ClearBtn_Click()
ClearForm ("")
End Sub
Private Sub Job_Change()
If FormEvents Then ClearForm ("Job")
End Sub
Private Sub Customer_Change()
If FormEvents Then ClearForm ("Customer")
End Sub
Private Sub Location_Change()
If FormEvents Then ClearForm ("Location")
End Sub
Private Sub PickBtn_Click()
Dim i As Integer
Sheet1.Activate
For i = 1 To Range("A10000").End(xlUp).row
If Cells(i, 2) = Results.List(Results.ListIndex) Then
Rows(i).Select
Me.Range("Selection:G").Value = Date
End If
Next i
End Sub
Private Sub SearchBtn_Click()
Dim SearchTerm As String
Dim SearchColumn As String
Dim RecordRange As Range
Dim FirstAddress As String
Dim FirstCell As Range
Dim RowCount As Integer
' Display an error if no search term is entered
If Job.Value = "" And Customer.Value = "" And Location.Value = "" Then
MsgBox "No search term specified", vbCritical + vbOKOnly
Exit Sub
End If
' Work out what is being searched for
If Job.Value <> "" Then
SearchTerm = Job.Value
SearchColumn = "Job"
End If
If Customer.Value <> "" Then
SearchTerm = Customer.Value
SearchColumn = "Customer"
End If
If Location.Value <> "" Then
SearchTerm = Location.Value
SearchColumn = "Location"
End If
Results.Clear
' Only search in the relevant table column i.e. if somone is
searching Location
' only search in the Location column
With Range("Table1[" & SearchColumn & "]")
' Find the first match
Set RecordRange = .Find(SearchTerm, LookIn:=xlValues)
' If a match has been found
If Not RecordRange Is Nothing Then
FirstAddress = RecordRange.Address
RowCount = 0
Do
' Set the first cell in the row of the matching value
Set FirstCell = Range("B" & RecordRange.row)
' Add matching record to List Box
Results.AddItem
Results.List(RowCount, 0) = FirstCell(1, 1)
Results.List(RowCount, 1) = FirstCell(1, 2)
Results.List(RowCount, 2) = FirstCell(1, 3)
Results.List(RowCount, 3) = FirstCell(1, 4)
Results.List(RowCount, 4) = FirstCell(1, 5)
Results.List(RowCount, 5) = FirstCell(1, 7)
RowCount = RowCount + 1
' Look for next match
Set RecordRange = .FindNext(RecordRange)
' When no further matches are found, exit the sub
If RecordRange Is Nothing Then
Exit Sub
End If
' Keep looking while unique matches are found
Loop While RecordRange.Address <> FirstAddress
Else
' If you get here, no matches were found
Results.AddItem
Results.List(RowCount, 0) = "Nothing Found"
End If
End With
End Sub
Private Sub UserForm_Initialize()
FormEvents = True
End Sub
Add another column in the list box to hold the row number.
Results.List(RowCount, 6) = FirstCell.Row
And then code becomes
Private Sub PickBtn_Click()
Dim r as long
r = Results.List(Results.ListIndex,6)
Range(r, 7).Value = Date
End Sub
I am trying to create a form:
where you are able to select multiple items and it display in excel sheet
I was able to do so for selecting only one item in a list, but when changed to multi select I don't know how to link the form and the worksheet together.
Also - how do I make it display in the "database" portion of my form here:
code for Module 1
Option Explicit
Sub Reset()
Dim iRow As Long
iRow = [Counta(Database!A:A)] ' identifying the last row
With frmForm
.txtName.Value = ""
.txtAge.Value = "'"
.lstInvited.Clear
.lstInvited.AddItem "Aya"
.lstInvited.AddItem "Bi"
.lstInvited.AddItem "Britt"
.lstInvited.AddItem "Cami"
.lstInvited.AddItem "Sarl"
.lstInvited.AddItem "Ch"
.cmbTeacher.Clear
.cmbTeacher.AddItem "A"
.cmbTeacher.AddItem "Bia"
.cmbTeacher.AddItem "Cami"
.cmbTeacher.AddItem "China"
.cmbStudy.Clear
.cmbStudy.AddItem "1"
.cmbStudy.AddItem "2"
.cmbStudy.AddItem "3"
.cmbStudy.AddItem "45"
.lstAction.Clear
.lstAction.AddItem "Wants to study again"
.lstAction.AddItem "Other, Please specify in Notes"
.lstInfo.Clear
.lstInfo.AddItem "Open-minded"
.lstInfo.AddItem "Needs to study in a different language"
.lstInfo.AddItem "Other, Please specify in Notes"
.lstZoom.Clear
.lstZoom.AddItem "Attentive"
.lstZoom.AddItem "Not interactive/ Not connected"
.lstZoom.AddItem "Occupied"
.lstZoom.AddItem "Other, Please specify in Notes"
.txtNotes.Value = ""
.lstDatabase.ColumnCount = 10
.lstDatabase.ColumnHeads = True
If iRow > 1 Then
.lstDatabase.RowSource = "Database!A2:J" & iRow
Else
.lstDatabase.RowSource = "Database!A2:J2"
End If
End With
End Sub
Sub Submit()
Dim sh As Worksheet
Dim iRow As Long
Set sh = ThisWorkbook.Sheets("Database")
iRow = [Counta(Database!A:A)] + 1
With sh
.Cells(iRow, 1) = frmForm.txtName.Value
.Cells(iRow, 2) = frmForm.lstInvited.Value
.Cells(iRow, 3) = frmForm.txtAge.Value
.Cells(iRow, 4) = frmForm.cmbTeacher.Value
.Cells(iRow, 5) = frmForm.cmbStudy.Value
.Cells(iRow, 6) = frmForm.dtpDate.Value
.Cells(iRow, 7) = frmForm.lstAction.Value
.Cells(iRow, 8) = frmForm.lstInfo.Value
.Cells(iRow, 9) = frmForm.lstZoom.Value
.Cells(iRow, 10) = frmForm.txtNotes.Value
End With
End Sub
Sub Show_Form()
frmForm.Show
End Sub
`
and then here is the code for form (frmForm)
Private Sub cmdReset_Click()
Dim msgValue As VbMsgBoxResult
msgValue = MsgBox(" Do you want to reset the form?", vbYesNo + vbInformation, "Confirmation")
If msgValue = vbNo Then Exit Sub
Call Reset
End Sub
Private Sub cmdSave_Click()
Dim msgValue As VbMsgBoxResult
msgValue = MsgBox(" Do you want to save the data?", vbYesNo + vbInformation, "Confirmation")
If msgValue = vbNo Then Exit Sub
Call Submit
Call Reset
End Sub
Private Sub lstInvited_Initialize()
Me.lstInvited.RowSource = strInvitedList
End Sub
Private Sub lstAction_Initialize()
Me.lstAction.RowSource = strDVActionList
End Sub
Private Sub Frame1_Click()
End Sub
Private Sub lstAction_Click()
For i = 0 To lstAction.ListCount - 1
If lstAction.Selected(i) = True Then
ListBox2.AddItem
ListBox2.Column(0, (ListBox2.ListCount - 1)) = ListBox1.Column(0, i)
ListBox2.Column(1, (ListBox2.ListCount - 1)) = ListBox1.Column(1, i)
ListBox2.Column(2, (ListBox2.ListCount - 1)) = ListBox1.Column(2, i)
End If
Next
End Sub
Private Sub UserForm_Initialize()
Call Reset
End Sub
You'll need to loop through the list box. You can use the .ListCount property to get the number of rows (the index starts at 0 so use .ListCount - 1). You can check if the index is selected by using .Selected(i) where i is the loop counter.
So if your listbox is called ListBox1 you can do something like this to determine what rows are selected:
For i = 0 to ListBox1.Count - 1
If ListBox1.Selected(i) = True Then Debug.Print "Index " & i & " is selected"
Next i
Instead of the debug message you can add the information to your worksheet by using the listbox .List method, you'll need to use i for the row parameter and whatever number you need for the column parameter.
To add the information to the form you can use the .List method again to set those properties.
You may also want to look into assigning the values to an array as this would shorten your code.
i'm relatively new to VBA and have muddled my way through to almost achieving the system i set out to produce.
I have now reached a brick wall and have been smashing my head against it for some time, help with my paradigm (tome only i'm sure) would be very much appreciated!!
So i am able to search for records and populate my user form from that, what i would like to do is update the found record through the same form when clicking the update button which is present on said user form.
Private Sub btsearch_Click()
Dim totrows As Long
totrows = Worksheets("Report").Range("A1").CurrentRegion.Rows.Count
If Txtforename.Text = "" Then
MsgBox "Please enter guest name!!"
End If
For i = 2 To totrows
If Trim(Report.Cells(i, 1)) <> Trim(Txtforename.Text) And i = totrows Then
MsgBox "Guest Not Found"
End If
If Trim(Report.Cells(i, 1)) = Trim(Txtforename.Text) Then
Txtforename.Text = Report.Cells(i, 1)
Txtsurename.Text = Report.Cells(i, 2)
Cboidtype.Text = Report.Cells(i, 3)
txtidnumber.Text = Report.Cells(i, 4)
Cboroomno.Text = Report.Cells(i, 5)
txtcheckin.Text = Report.Cells(i, 6)
txtcheckout.Text = Report.Cells(i, 7)
Cbopaymenttype.Text = Report.Cells(i, 9)
Txttotalpayment.Text = Report.Cells(i, 10)
cmbouser.Text = Report.Cells(i, 11)
Exit For
End If
Next i
End Sub
Private Sub btnupdate_Click()
answer = MsgBox("Would you like to update guest details?", vbYesNo +
vbQuestion, "Update Record")
If answer = vbYes Then
Cells(currentrow, 1) = Txtforename.Text
Cells(currentrow, 2) = Txtsurename.Text
Cells(currentrow, 3) = Cboidtype.Text
Cells(currentrow, 4) = txtidnumber.Text
Cells(currentrow, 5) = Cboroomno.Text
Cells(currentrow, 6) = txtcheckin.Text
Cells(currentrow, 7) = txtcheckout.Text
Cells(currentrow, 9) = Cbopaymenttype.Text
Cells(currentrow, 10) = Txttotalpayment.Text
Cells(currentrow, 11) = cmbouser.Text
End If
End Sub
Something like this should work (untested). The matched row is stored in a global variable so you can update it when you're finished editing
Dim CurrentRow As Range 'to store the matched row
Private Sub btsearch_Click()
Dim totrows As Long, i As Long, fName
fName = Trim(Txtforename.Text)
If Len(fName) = 0 Then
MsgBox "Please enter guest name!!"
Exit Sub
End If
totrows = Report.Range("A1").CurrentRegion.Rows.Count
Set CurrentRow = Nothing 'clear any previous row
For i = 2 To totrows
If Trim(Report.Cells(i, 1)) = fName Then
Set CurrentRow = Report.Rows(i)
LoadRow CurrentRow '<< save the matched row
Exit For
End If
Next i
If CurrentRow Is Nothing Then
MsgBox "not found!"
End If
End Sub
Private Sub btnupdate_Click()
If MsgBox("Would you like to update guest details?", _
vbYesNo + vbQuestion, "Update Record") = vbYes Then
SaveRow CurrentRow
End If
End Sub
'load a row of data into the userform
Sub LoadRow(rw As Range)
With rw
Txtforename.Text = .Cells(1).Value
Txtsurename.Text = .Cells(2).Value
Cboidtype.Text = .Cells(3).Value
'etc etc
End With
End Sub
'save the userform data back to the sheet
Sub SaveRow(rw As Range)
With rw
.Cells(1).Value = Txtforename.Text
.Cells(2).Value = Txtsurename.Text
.Cells(3).Value = Cboidtype.Text
'etc etc
End With
End Sub
First thing I would check is the result value of the MsgBox. MsgBox always returns an integer, and answer is a variant.
Secondly I would declare answer as an integer. Together it could become this : . . .
Dim answer As Integer
answer = Msgbox("Would you ... ecord")
Debug.Print "' answer := " & answer ' display result in immediate-window
MsgBox "' answer := " & answer ' or display the result with a msgbox
If answer = vbYes Then
Debug.Print "' then"
' while you are busy debugging, display this value too
Debug.Print "' currentrow := " & currentrow
. . .
Else
Debug.Print "' else"
End If
. . .
I need a code for this userform, when I choose some item from ComboBox to fill textboxes and optionbutton from my "Sheet1" table.
Something like this would do what you are trying to accomplish. Just insert this wherever you are pulling the other data out.
If Sheets("SheetName").Cells(row, 5) = "Male" Then
OptionButton1 = True
OptionButton2 = False
ElseIf Sheets("SheetName").Cells(row, 5) = "Female" Then
OptionButton1 = False
OptionButton2 = True
Else
MsgBox("Sex not Male or Female")
End If
This is the code for this userform:
Dim Project As Workbook
Dim SheeT As Worksheet
Dim Closing As Boolean
Private Sub UserForm_Initialize()
Set Project = Workbooks("Navi4.xlsm") ' ThisWorkbook
Set SheeT = Project.Worksheets("Sheet1")
With SheeT
ComboBox1.List = .Range("C2", .Range("C" & Rows.Count).End(xlUp)).Value
End With
End Sub
Private Sub ComboBox1_Change()
Dim Item As Long
Item = ComboBox1.ListIndex
If Item = -1 Then
Exit Sub ' nothing selected
End If
TextBox1.Value = SheeT.Range("C" & Item + 2).Value
TextBox2.Value = SheeT.Range("D" & Item + 2).Value
If Sheets("Sheet1").Range("E" & Item + 2).Value = "Male" Then
OptionButton1 = True
OptionButton2 = False
ElseIf Sheets("Sheet1").Range("E" & Item + 2).Value = "Female" Then
OptionButton1 = False
OptionButton2 = True
Else
MsgBox ("Sex not Male or Female")
End If
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Closing = True
End Sub