I have a userform that has a combo box at the top which will activate specific sheets based on the selection in the combobox. I have a search that works but it will only search and display data from sheet1 but I would like it to search and display data based on the active sheet. I have tried to update the code multiple different ways and place activesheet in place of sheet1 but it always errors out. If someone could assist with the code please let me know and I would appreciate it.
Private Sub cmdSearch_Click()
Dim totRows As Long, i As Long
totRows = Sheet1.range("A1").CurrentRegion.Rows.count
If txtname.Text = "" Then
MsgBox "Enter the name in the name block that you want to search"
End If
For i = 2 To totRows
If Trim(Sheet1.Cells(i, 1)) <> Trim(txtname.Text) And i = totRows Then
MsgBox "Name not found"
End If
If Trim(Sheet1.Cells(i, 1)) = Trim(txtname.Text) Then
txtname.Text = Sheet1.Cells(i, 1)
txtposition.Text = Sheet1.Cells(i, 2)
txtassigned.Text = Sheet1.Cells(i, 3)
cmbsection.Text = Sheet1.Cells(i, 4)
txtdate.Text = Sheet1.Cells(i, 5)
txtjoint.Text = Sheet1.Cells(i, 7)
txtDAS.Text = Sheet1.Cells(i, 8)
txtDEROS.Text = Sheet1.Cells(i, 9)
txtDOR.Text = Sheet1.Cells(i, 10)
txtTAFMSD.Text = Sheet1.Cells(i, 11)
txtDOS.Text = Sheet1.Cells(i, 12)
txtPAC.Text = Sheet1.Cells(i, 13)
ComboTSC.Text = Sheet1.Cells(i, 14)
txtTSC.Text = Sheet1.Cells(i, 15)
txtAEF.Text = Sheet1.Cells(i, 16)
txtPCC.Text = Sheet1.Cells(i, 17)
txtcourses.Text = Sheet1.Cells(i, 18)
txtseven.Text = Sheet1.Cells(i, 19)
txtcle.Text = Sheet1.Cells(i, 20)
txtnote.Text = Sheet1.Cells(i, 21)
Exit For
End If
Next i
End Sub
Combobox:
Private Sub ComboBox1_Change()
Dim actWsh As String
actWsh = ComboBox1.Text
Worksheets(actWsh).Select
End Sub
Comboboxbutton:
Private Sub CommandButton4_Click()
Me.ComboBox1.Clear
Dim strWs As String
Dim j As Integer
For j = 1 To ThisWorkbook.Sheets.count
Me.ComboBox1.AddItem Sheets(j).Name
Next
End Sub
Code that worked:
Private Sub cmdSearch_Click()
Dim wRow
If txtname.Text = "" Then
MsgBox "Enter the name in the name block that you want to search": Exit Sub
End If
With ActiveSheet
wRow = Application.Match(txtname.Text, .Columns(1), 0)
If Not IsError(wRow) Then
txtname.Text = .Cells(wRow, 1)
txtposition.Text = .Cells(wRow, 2)
txtassigned.Text = .Cells(wRow, 3)
cmbsection.Text = .Cells(wRow, 4)
txtdate.Text = .Cells(wRow, 5)
txtjoint.Text = .Cells(wRow, 7)
txtDAS.Text = .Cells(wRow, 8)
txtDEROS.Text = .Cells(wRow, 9)
txtDOR.Text = .Cells(wRow, 10)
txtTAFMSD.Text = .Cells(wRow, 11)
txtDOS.Text = .Cells(wRow, 12)
txtPAC.Text = .Cells(wRow, 13)
ComboTSC.Text = .Cells(wRow, 14)
txtTSC.Text = .Cells(wRow, 15)
txtAEF.Text = .Cells(wRow, 16)
txtPCC.Text = .Cells(wRow, 17)
txtcourses.Text = .Cells(wRow, 18)
txtseven.Text = .Cells(wRow, 19)
txtcle.Text = .Cells(wRow, 20)
txtnote.Text = .Cells(wRow, 21)
Else
MsgBox "Name not found"
End If
End With
End Sub
Step 1: On the topmost line of your code, add this line so that you may access this variable for later.
Dim actWsh As Workbook
Step 2: Replace your ComboBox1_Change() code with the one below. This will set the selected sheet to the variable actWsh
Private Sub ComboBox1_Change()
set actWsh = Worksheets(ComboBox1.Text)
actWsh.Activate
End Sub
Step 3: On your cmdSearch_Click() method, replace all Sheet1 with actWsh.
Hope this helps. :) Let me know if you have any other questions.
Related
when I run this VBA macro I get the same result despite putting in different nurse id thanks, this code came from a video that I watch and has been modified to work with multiple criteria
Sub finddata()
Dim nursenumber As String
Dim finalrow As Integer
Dim i As Integer
Dim course As Integer
Dim nurserow As Integer
nursenumber = InputBox("please enter nurse number")
nurserow = InputBox("please enter nurse row")
finalrow = Sheets("S1").Range("A10000").End(xlUp).Row
course = ADORIE
'fire update
For i = 2 To finalrow
Worksheets("S1").Activate
If Cells(i, 1) = nursenumber & Cells(i, 7) = "FIRE" Then
Cells(i, 9).Copy
Worksheets("database").Activate
Cells(nurserow, 2).PasteSpecial
End If
'cpr
If Cells(i, 1) = nursenumber & Cells(i, 7) = "CPRNURL4" Or _
Cells(i, 7) = "BUCPRBYS" Or Cells(i, 7) = "BUCPREMS" Or _
Cells(i, 7) = "CPRACLSR" Or Cells(i, 7) = "CPRADULT" Or _
Cells(i, 7) = "CPRALIED" Or Cells(i, 7) = "CPRBASIC" Or _
Cells(i, 7) = "CPRBYST" Or Cells(i, 7) = "CPRCO567" Or _
Cells(i, 7) = "CPRMANHA" Or Cells(i, 7) = "CPRMCORP" Or _
Cells(i, 7) = "CPRNURL4" Then
Cells(i, 9).Copy
Worksheets("database").Activate
Cells(nurserow, 3).PasteSpecial
Next i
End Sub
Following my comments above, also, your code is screaming for a Select Case instead of your multiple Or.
Code
Sub finddata()
Dim nursenumber As String
Dim finalrow As Integer
Dim i As Integer
Dim course As Integer
Dim nurserow As Integer
nursenumber = InputBox("please enter nurse number")
nurserow = InputBox("please enter nurse row")
finalrow = Sheets("S1").Range("A10000").End(xlUp).Row
course = ADORIE
With Worksheets("S1")
For i = 2 To finalrow
If .Cells(i, 1) = nursenumber Then
Select Case .Cells(i, 7).Value
Case "FIRE"
.Cells(i, 9).Copy Destination:=Worksheets("database").Cells(nurserow, 2)
Case "CPRNURL4", "BUCPRBYS", "CPRACLSR", "CPRADULT", "CPRALIED", "CPRBASIC", "CPRBYST", "CPRCO567", "CPRMANHA", "CPRMCORP", "CPRNURL4"
.Cells(i, 9).Copy Destination:=Worksheets("database").Cells(nurserow, 3)
End Select
End If
Next i
End With
End Sub
I wonder if someone can help me please. I am a new VBA user and made a timesheet using guidelines on this website.
Currently, when the command button 2 is clicked, the data captured on the timesheet is transferred to sheet called 'Data' within the same worksheet. What I want is to transfer it to another workbook's sheet saved in another folder. Full path of sheet is C:\Users\mohskhan\Desktop\masterts.xlsm. Please can someone help.
Current coding is as follows:
Private Sub CommandButton2_Click()
ComboBox1.Enabled = True
Dim ssheet As Worksheet
Set ssheet = ThisWorkbook.Sheets("Data")
nr = ssheet.Cells(Rows.Count, 1).End(xlUp).Row + 1
ssheet.Cells(nr, 1) = CDate(Me.TextBox1)
ssheet.Cells(nr, 2) = (Me.TextBox2)
ssheet.Cells(nr, 3) = (Me.ComboBox1)
ssheet.Cells(nr, 4) = (Me.ComboBox2)
ssheet.Cells(nr, 5) = (Me.TextBox3)
ssheet.Cells(nr, 6) = (Me.TextBox4)
ssheet.Cells(nr, 7) = (Me.TextBox5)
ssheet.Cells(nr, 8) = (Me.TextBox12)
ssheet.Cells(nr, 9) = (Me.ComboBox3)
ssheet.Cells(nr, 11) = Evaluate("=NOW()-TODAY()")
ssheet.Cells(nr, 14) = (Me.TextBox35)
ssheet.Cells(nr, 21) = (Me.TextBox6)
ssheet.Cells(nr, 22) = (Me.ComboBox4)
ssheet.Cells(nr, 23) = (Me.TextBox7)
ssheet.Cells(nr, 24) = (Me.TextBox23)
ssheet.Cells(nr, 25) = (Me.TextBox8)
ssheet.Cells(nr, 26) = (Me.ComboBox5)
ssheet.Cells(nr, 27) = (Me.TextBox9)
ssheet.Cells(nr, 28) = (Me.TextBox24)
ssheet.Cells(nr, 29) = (Me.TextBox10)
ssheet.Cells(nr, 30) = (Me.ComboBox6)
ssheet.Cells(nr, 31) = (Me.TextBox11)
ssheet.Cells(nr, 32) = (Me.TextBox25)
ssheet.Cells(nr, 34) = (Me.TextBox36)
ssheet.Cells(nr, 35) = (Me.TextBox37)
ComboBox1 = ""
ComboBox2 = ""
ComboBox3 = ""
TextBox3 = ""
TextBox4 = ""
TextBox12 = ""
TextBox5 = ""
ComboBox4 = ""
ComboBox5 = ""
ComboBox6 = ""
TextBox6 = ""
TextBox7 = ""
TextBox8 = ""
TextBox9 = ""
TextBox10 = ""
TextBox11 = ""
TextBox23 = ""
TextBox24 = ""
TextBox25 = ""
TextBox35 = ""
TextBox36 = ""
TextBox37 = ""
CommandButton1.Enabled = False
CommandButton2.Enabled = False
End Sub
Updated:
Private Sub CommandButton2_Click()
Const FullName = "C:\Users\Owner\Downloads\masterts.xlsm"
Dim CloseWorkbook As Boolean
Dim WB As Workbook
ComboBox1.Enabled = True
On Error Resume Next
Set WB = Workbooks("masterts.xlsm")
CloseWorkbook = Err.Number = 0
On Error GoTo 0
If WB Is Nothing Then Set WB = Workbooks.Open(FullName)
With WB.Worksheets("Data")
With .Range("A" & .Rows.Count).End(xlUp).Offset(1)
.Resize(1, 13).Value = Array(CDbl(CDate(Me.TextBox1)), Me.TextBox2, Me.ComboBox1.Value, Me.ComboBox2.Value, Me.TextBox3.Value, Me.TextBox4.Value, _
Me.TextBox5.Value, Me.TextBox12.Value, Me.ComboBox3.Value, CDbl(TimeValue(Now)), Me.TextBox35.Value, Me.TextBox6.Value, Me.ComboBox4.Value)
End With
With .Range("U" & .Rows.Count).End(xlUp).Offset(1)
.Resize(1, 12).Value = Array(Me.TextBox7.Value, Me.TextBox23.Value, Me.TextBox8.Value, Me.ComboBox5.Value, Me.TextBox9.Value, Me.TextBox24.Value, Me.TextBox10.Value, Me.ComboBox6.Value, Me.TextBox11.Value, Me.TextBox25.Value, Me.TextBox36.Value, Me.TextBox37.Value)
End With
.Save
End With
If CloseWorkbook Then WB.Close SaveChanges:=False
CommandButton1.Enabled = False
CommandButton2.Enabled = False
End Sub
Should do the trick
Workbooks.Open("C:\Users\mohskhan\Desktop\masterts.xlsm")
Set ssheet = Workbooks("masterts.xlsm").Worksheets("Data")
'Run code
EDIT: I suggest turning off screen updating while you execute the data transfer
Application.ScreenUpdating = False
'Code to execute
Application.ScreenUpdating = True
I'm having issues with piece of code. We use the following to search a log for a specific information, populate a chart and then print and clear the chart once completed.
The thing is, if we change the search criteria from CIS to Inbound (or anything else for that matter) it refuses to populate the chart with the information from the log, but still prints out the chart headers.
This is the code we're using:
Private Sub cmdprint_Click()
Dim sdsheet As Worksheet, ersheet As Worksheet
Set sdsheet = Workbooks("HD Project.xls").Sheets("HelpdeskLogg")
Set ersheet = Workbooks("HD Project.xls").Sheets("report")
dlr = sdsheet.Cells(Rows.Count, 1).End(xlUp).Row
rlr = ersheet.Cells(Rows.Count, 1).End(xlUp).Row
y = 2
For x = 2 To dlr
If UCase(sdsheet.Cells(x, 6)) = "Inbound" And CDate(sdsheet.Cells(x, 3)) >= CDate(Me.txtdatestart) And CDate(sdsheet.Cells(x, 3)) <= CDate(Me.txtdateend) Then
ersheet.Cells(y, 1) = CDate(sdsheet.Cells(x, 3))
ersheet.Cells(y, 2) = sdsheet.Cells(x, 6)
ersheet.Cells(y, 3) = sdsheet.Cells(x, 7)
ersheet.Cells(y, 4) = sdsheet.Cells(x, 8)
ersheet.Cells(y, 5) = sdsheet.Cells(x, 9)
ersheet.Cells(y, 6) = sdsheet.Cells(x, 10)
ersheet.Cells(y, 7) = sdsheet.Cells(x, 11)
ersheet.Cells(y, 8) = sdsheet.Cells(x, 12)
ersheet.Cells(y, 9) = sdsheet.Cells(x, 13)
y = y + 1
'On Error Resume Next
End If
Next x
Dim Lastrow As Integer
Lastrow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
Set printa = ersheet.Range("A1:i" & Lastrow)
printa.PrintOut
Sheets("report").Range("a2:i999").ClearContents
End Sub
Try changing:
UCase(sdsheet.Cells(x, 6)) = "Inbound" to
UCase(sdsheet.Cells(x, 6)) = "INBOUND"
Try changing:
UCase(sdsheet.Cells(x, 6)) = "Inbound" to
UCase(sdsheet.Cells(x, 6)) = "INBOUND"
This worked. Thank you for your help, barrleajo
I created a macro in Excel to mergue duplicated rows:
The idea is that if 2 rows or more have the same A B C columns, I mergue their D columns removing ABC duplicates.
I need to do this, but checking more colums.
My macro looks like this:
processingRow = 2
Do Until Cells(processingRow, 1).Value = ""
i = processingRow + 1
Do Until Cells(i, 1).Value = ""
If Cells(processingRow, 8) = Cells(i, 8) And _
Cells(processingRow, 12) = Cells(i, 12) And _
Cells(processingRow, 7) = Cells(i, 7) And _
Cells(processingRow, 6) = Cells(i, 6) And _
Cells(processingRow, 5) = Cells(i, 5) And _
Cells(processingRow, 4) = Cells(i, 4) And _
Cells(processingRow, 3) = Cells(i, 3) And _
Cells(processingRow, 2) = Cells(i, 2) And _
Cells(processingRow, 1) = Cells(i, 1) Then
If Cells(i, 14) <> "" Then
Cells(processingRow, 14) = Cells(processingRow, 14) & "," & Cells(i, 14)
End If
Rows(i).Delete
End If
i = i + 1
Loop
processingRow = processingRow + 1
Loop
When running the macro with 500 rows, it takes a while, but its still reasonable. But I need to run this macro in a excel with more than 2500 rows, and it takes so much time that its not practical anymore.
This is my first macro in excel using VBA, so I was wondering if there is a faster way to process rows/cells, since accessing them individually seems extremelly slow.
Any ideas?
EDITED: I missed that you weren't checking every column to determine what was a duplicate. This should be closer now:
Sub Tester()
Dim rngCheck As Range, rw As Range
Dim dict As Object, k As String, rwDup As Range
Dim rngDel As Range, tmp
Set dict = CreateObject("scripting.dictionary")
With ActiveSheet
Set rngCheck = .Range(.Cells(2, 1), _
.Cells(Rows.Count, 1).End(xlUp)).Resize(, 14)
End With
For Each rw In rngCheck.Rows
k = RowKey(rw)
If dict.exists(k) Then
Set rwDup = dict(k)
tmp = rw.Cells(14).Value
If Len(tmp) > 0 Then
rwDup.Cells(14).Value = rwDup.Cells(14).Value & "," & tmp
End If
If rngDel Is Nothing Then
Set rngDel = rw
Else
Set rngDel = Application.Union(rngDel, rw)
End If
Else
dict.Add k, rw
End If
Next rw
If Not rngDel Is Nothing Then rngDel.EntireRow.Delete
End Sub
'create a "key" for the row by joining all columns to be checked
Function RowKey(rw As Range) As String
Dim arr, x As Long, sep As String, rv As String
arr = Array(1, 2, 3, 4, 5, 6, 7, 8, 12)
For x = LBound(arr) To UBound(arr)
rv = rv & sep & rw.Cells(arr(x)).Value
sep = Chr(0)
Next x
RowKey = rv
End Function
I have the below piece of code to append new data to an existing Access table.
It takes around 35-40 minutes for me to upload about 6000 records...
Appreciate any help...
Sub Upload(Process_ID)
Dim Conn_DB As ADODB.Connection, CmdQuery As ADODB.Command, RecSet As ADODB.Recordset, StrSQL As String
Dim LastColumn As Integer, LastRow As Integer, ImportData(), I As Integer, ArrayRow As Integer
WS_Source.Select
LastRow = WS_Source.Cells(Rows.Count, 1).End(xlUp).Row
LastColumn = WS_Source.Cells(1, Columns.Count).End(xlToLeft).Column
'Load source data to array
ReDim ImportData(LastRow - 2, 25)
Select Case Process_ID
Case 1, 2, 3
For I = 2 To LastRow
ImportData(ArrayRow, 0) = Cells(I, 1) 'username
ImportData(ArrayRow, 1) = Cells(I, 2) 'creid
ImportData(ArrayRow, 2) = Cells(I, 3) 'roleid
ImportData(ArrayRow, 3) = Cells(I, 4) 'webtraceid
ImportData(ArrayRow, 4) = Cells(I, 5) 'timestamp
ImportData(ArrayRow, 5) = Cells(I, 6) 'action
ImportData(ArrayRow, 6) = Cells(I, 7) 'Anti Fact
ImportData(ArrayRow, 7) = Cells(I, 8) 'sourceid
ImportData(ArrayRow, 8) = Cells(I, 9) 'source
ImportData(ArrayRow, 9) = Cells(I, 10) 'personid
ImportData(ArrayRow, 10) = Cells(I, 11) 'personname
ImportData(ArrayRow, 11) = Cells(I, 12) 'orgid
ImportData(ArrayRow, 12) = Cells(I, 13) 'orgname
ImportData(ArrayRow, 13) = Cells(I, 14) 'rel type
ImportData(ArrayRow, 14) = Cells(I, 15) 'oldvalue
ImportData(ArrayRow, 15) = Cells(I, 16) 'new value
ImportData(ArrayRow, 16) = Cells(I, 17) 'startdate
ImportData(ArrayRow, 17) = Cells(I, 18) 'enddate
ImportData(ArrayRow, 18) = Cells(I, 19) 'status
ImportData(ArrayRow, 19) = Cells(I, 20) 'sourcetype
ImportData(ArrayRow, 20) = Cells(I, 21) 'final score
ImportData(ArrayRow, 21) = Cells(I, 22) 'ben
ImportData(ArrayRow, 22) = Cells(I, 23) 'wpc
ImportData(ArrayRow, 23) = Cells(I, 24) 'prw
ImportData(ArrayRow, 24) = Cells(I, 26) 'serial
ImportData(ArrayRow, 25) = Cells(I, 28) 'sample
ArrayRow = ArrayRow + 1
Next I
Case Else: Exit Sub
End Select
'Load array data to database
Set Conn_DB = New ADODB.Connection
With Conn_DB
.Provider = "microsoft.ACE.OLEDB.12.0"
.ConnectionString = Location_DataBase
End With
Conn_DB.Open
StrSQL = "SELECT *"
Set CmdQuery = New ADODB.Command
With CmdQuery
.ActiveConnection = Conn_DB
.CommandText = StrSQL
.CommandType = adCmdText
End With
For I = 0 To ArrayRow - 1
Set RecSet = New ADODB.Recordset
With RecSet
Set .Source = CmdQuery
.CursorType = adOpenKeyset
.CursorLocation = adUseClient
.LockType = adLockOptimistic
.Open "tbl_crereport"
End With
If RecSet.State = adStateOpen Then
With RecSet
.AddNew
Select Case Process_ID
Case 1, 2, 3
.Fields("processedby") = ImportData(I, 0)
.Fields("creid") = ImportData(I, 1)
.Fields("roleid") = ImportData(I, 2)
.Fields("webtraceid") = ImportData(I, 3)
.Fields("processeddate") = ImportData(I, 4)
.Fields("action") = ImportData(I, 5)
.Fields("antifact") = ImportData(I, 6)
.Fields("sourceid") = ImportData(I, 7)
.Fields("source") = ImportData(I, 8)
.Fields("personid") = ImportData(I, 9)
.Fields("personname") = ImportData(I, 10)
.Fields("orgid") = ImportData(I, 11)
.Fields("orgname") = ImportData(I, 12)
.Fields("relationshiptype") = ImportData(I, 13)
.Fields("oldvalue") = ImportData(I, 14)
.Fields("newvalue") = ImportData(I, 15)
.Fields("startdate") = ImportData(I, 16)
.Fields("enddate") = ImportData(I, 17)
.Fields("crestatus") = ImportData(I, 18)
.Fields("sourcetype") = ImportData(I, 19)
.Fields("finalscore") = ImportData(I, 20)
.Fields("ben") = ImportData(I, 21)
.Fields("wpc") = ImportData(I, 22)
.Fields("prw") = ImportData(I, 23)
.Fields("Serial") = ImportData(I, 24)
.Fields("sample") = ImportData(I, 25)
.Fields("allocatedto") = User_ID
.Fields("allocationdate") = Now()
.Fields("updatedby") = User_ID
.Fields("updatedate") = Now()
.Fields("status") = 1
Case Else: Exit Sub
End Select
.Update
End With
End If
RecSet.Close
Set RecSet = Nothing
Next I
'Close database
On Error Resume Next
RecSet.Close
Conn_DB.Close
Set CmdQuery = Nothing
Set RecSet = Nothing
Set Conn_DB = Nothing
End Sub
Appreciate any help to speedup the code.
I'd not be able to use this at the current speed.
Thanks,
g
3 small tips:
if you have indexes in Access the append/update can become significantly slower than you would expect. You might want to remove these indexes while data is being added.
have you tried writing the VBA in Access instead? That way you could import the Excel file in bulk, do the necessary data manipulation and load it into the table you need in one go (not record by record).
My VBA might be rusty but I think you don't have to create a recordset per new record you are appending. Create it once before the cycle and just don't close it until all records are loaded in.
Regards,