So I have had a couple of questions I've asked regarding excel VBA, and I appreciate you all bearing with me as I stumble through learning about all this. Your answers have been a tremendous help and learning experience.
So far, I have a subroutine whose main responsibility is to write all of the values collected through a user form with various validations and dynamic comboboxes. My final task is to get this Subroutine to assign a hyperlink to the location selected by an earlier loop. But with my current syntax, I'm getting a "run-time error '1004' method '_default' of object 'range' failed". Some research proved that the cell coordinates require a .address property after them in order to avert this error, but it did not resolve the issue. The code is below:
Option Explicit
Dim cnt As Integer
Dim i As Long, rowOff As Long
Dim dateSel As String
Dim timeSel As String
Dim branch As String
Dim sht As Worksheet
Dim cel As Range
Dim matchingHeader As Range
Public Sub UserForm_Initialize()
'clear form
BranchBox.Value = ""
DateBox.Value = ""
TimeBox.Value = ""
'populate sheet names from each branch
For Each sht In ActiveWorkbook.Sheets
If sht.Name = "ApplicantInfo" Then
'Do Nothing
Else
Me.BranchBox.AddItem sht.Name
End If
Next sht
End Sub
Public Sub HoldButton_Click() 'revisit... throwing Time message box regardless what's selected
If TimeBox.Value <> "" Then
If DateBox.Value <> "" Then
If BranchBox.Value <> "" Then
sht.Cells(rowOff, i).Value = "-"
'Save workbook
Else
MsgBox "You must select a branch for your appointment"
End If
Else
MsgBox "You must select a date for your appointment"
End If
Else
MsgBox "You must select a time for your appointment"
End If
End Sub
Private Sub ResetButton_Click()
FirstName.Value = ""
LastName.Value = ""
EMail.Value = ""
Phone.Value = ""
Skills.Value = ""
'BranchBox.Value = "" throws error
DateBox.Value = ""
TimeBox.Value = ""
End Sub
Private Sub ScheduleButton_Click()
Dim row As Long, column As Long
Dim linkDisplay As String
'test for RowOff and i <> 0
If IsNull(BranchBox) = True Then
MsgBox "Select a branch for you interview before you click schedule"
Else
If IsNull(DateBox) = True Then
MsgBox "Select a date for you interview before you click schedule"
Else
If IsNull(TimeBox) = True Then
MsgBox "Select a time for you interview before you click schedule"
Else
'find first empty row in applicant profile tab.
'Insert applicant information in free row
'parse applicant name as a link to found free row above
'replace "-" placeholder for held appointment with applicant name as a link
Call GetFirstEmptyRow
'write selected values into row
Dim InfoRow As Integer
InfoRow = ActiveCell.row
ActiveCell.Value = ActiveCell.Offset(-5, 0).Value + 5
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = LastName.Value
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = FirstName.Value
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = EMail.Value
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = Phone.Value
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = Skills.Value
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = BranchBox.Value
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = DateBox.Value
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = TimeBox.Value
branch = BranchBox.Value
Set sht = ActiveWorkbook.Worksheets(branch)
dateSel = DateBox.Value
timeSel = TimeBox.Value
'scan for selected date
For i = 2 To sht.Rows.Count
Set cel = sht.Cells(i, 1)
If cel.Value = dateSel Then
column = i
Exit For
End If
Next i
'Scan for selected time
For i = 2 To sht.Columns.Count
Set cel = sht.Cells(1, i)
If CStr(cel.Value) = timeSel Then
row = i
Exit For
End If
Next i
linkDisplay = LastName.Value & ", " & FirstName.Value
'This is the error
sht.Hyperlinks.Add Anchor:=sht.Cells(row, column).Address, Address:="", SubAddress:=ActiveWorkbook.Worksheets("ApplicantInfo").Cells(InfoRow, 1).Address, TextToDisplay:=linkDisplay
'end of validations
End If
End If
End If
End Sub
Public Sub GetFirstEmptyRow()
Set sht = ActiveWorkbook.Worksheets("ApplicantInfo")
sht.Activate
Range("A1").Select
Do
If IsEmpty(ActiveCell) = False Then
ActiveCell.Offset(1, 0).Select
End If
Loop Until IsEmpty(ActiveCell) = True
End Sub
Public Sub Save()
End Sub
Public Sub TimeBox_Change()
End Sub
Public Sub BranchBox_Change()
'clear Date Box Values
For i = DateBox.ListCount - 1 To 0 Step -1
DateBox.RemoveItem i
Next i
'clear Time Box Values
i = 0
For i = TimeBox.ListCount - 1 To 0 Step -1
TimeBox.RemoveItem i
Next i
'reset i to 0
i = 0
'populate dates
Me.DateBox.List = Worksheets(BranchBox.Value).Range("A2:A31").Value
End Sub
Public Sub DateBox_Change()
branch = BranchBox.Value
Set sht = ActiveWorkbook.Worksheets(branch)
dateSel = DateBox.Value
'Get Row to scan
For i = 2 To sht.Rows.Count
Set cel = sht.Cells(i, 1)
If cel.Value = dateSel Then
rowOff = i
Exit For
End If
Next i
'Scan selected row for blank cells
For i = 2 To sht.Columns.Count
Set cel = sht.Cells(rowOff, i)
If CStr(cel.Value) = "" Then
Set matchingHeader = sht.Cells(1, i)
TimeBox.AddItem matchingHeader.Text
End If
Next i
Me.TimeBox.AddItem ("No Appointments Available")
End Sub
This is the line which errors:
sht.Hyperlinks.Add Anchor:=sht.Cells(row, column).Address, _
Address:="", _
SubAddress:=ActiveWorkbook.Worksheets("ApplicantInfo") _
.Cells(InfoRow, 1).Address, _
TextToDisplay:=linkDisplay
Help is much appreciated! Thanks in advance!
sht.Hyperlinks.Add Anchor:=sht.Cells(row, column), _
Address:="", _
SubAddress:="'ApplicantInfo'!" & Cells(InfoRow, 1).Address(False, False), _
TextToDisplay:=linkDisplay
I'd typically use a utility method for this type of thing though.
E.g. something like:
Sub CreateHyperlink(FromCell As Range, ToCell As Range, Optional LinkText As String = "")
Dim subAddr, txt
subAddr = ToCell.Address(False, False)
If FromCell.Worksheet.Name <> ToCell.Worksheet.Name Then
subAddr = "'" & ToCell.Worksheet.Name & "'!" & subAddr
End If
txt = IIf(LinkText <> "", LinkText, FromCell.Value)
If Len(txt) = 0 Then txt = "Go"
With FromCell.Worksheet
.Hyperlinks.Add Anchor:=FromCell, Address:="", _
SubAddress:=subAddr, TextToDisplay:=txt
End With
End Sub
Related
I am comparing 2 worksheets based on a key and write the results in the new workbook. KEY column is A.
2 workbooks are Todays and yesterdays file.
I need to compare todays file with yesterdays file. Below are my scenarios:
If KEY matches in both the Worksheets and if all the columns of that corresponding KEY matches that is from (B:E) , then in F column the value should be NO CHANGE
If KEY matches in both the Worksheets and if any of the columns does not match corresponding to the KEY (B:E), then F column should have value CHANGED
If KEY does not match then F column should have value NEW RECORD
Below is my code writing logic is overriding my values and they are writing records from my yesterdays file instead if todays file :
'ASSUMPTIONS:
'Data begins in cell A1 of each worksheet
'Data is continuous (does not have blank rows or columns)
'Comparison Key should be in column A of each sheet and should NEVER be blank
Sub CompareArrays()
Dim BookOne As String, BookTwo As String, BookThree As String
Dim WorkbookOne As Workbook, WorkbookTwo As Workbook, WorkbookThree As Workbook
Dim SheetOne As Worksheet, SheetTwo As Worksheet, SheetThree As Worksheet
Dim Keytocompare1 As String
Dim Keytocompare2 As String
Dim Keytocompare3 As String
Dim Keytocompare4 As String
Dim Keytocompare5 As String
Sheet1.Cells.ClearContents
'Select Path for First Workbook
MsgBox "Select Today's Common Customer File"
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = False
.Title = "SELECT BOOK ONE"
.Show
BookOne = .SelectedItems(1)
End With
'Select Path for Second Workbook
MsgBox "Select Yesterday's Common Customer File"
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = False
.Title = "SELECT BOOK TWO"
.Show
BookTwo = .SelectedItems(1)
End With
'Select Path for Output Workbook
MsgBox "Select Output Common Customer File"
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = False
.Title = "SELECT BOOK THREE"
.Show
BookThree = .SelectedItems(1)
End With
Application.Workbooks.Open BookOne
Set SheetOne = ActiveWorkbook.Worksheets("Sheet1") '
Application.Workbooks.Open BookTwo
Set SheetTwo = ActiveWorkbook.Worksheets("Sheet1") '
Application.Workbooks.Open BookThree
Set SheetThree = ActiveWorkbook.Worksheets("Sheet1") '
Windows("Today.xlsx").Activate
Sheets("Sheet1").Select
Range("A1").Select
Do While ActiveCell.Value <> ""
Keytocompare1 = ActiveCell.Value
Keytocompare2 = ActiveCell.Offset(0, 1).Value
Keytocompare3 = ActiveCell.Offset(0, 2).Value
Keytocompare4 = ActiveCell.Offset(0, 3).Value
Keytocompare5 = ActiveCell.Offset(0, 4).Value
Windows("yesterday.xlsx").Activate
Sheets("Sheet1").Select
Range("A1").Select
Do While ActiveCell.Value <> ""
If ActiveCell.Value = Keytocompare1 Then
If ((ActiveCell.Offset(0, 1).Value = Keytocompare2) And (ActiveCell.Offset(0, 2).Value = Keytocompare3) And (ActiveCell.Offset(0, 3).Value = Keytocompare4) And (ActiveCell.Offset(0, 4).Value = Keytocompare5)) Then
Windows("Output.xlsx").Activate
Sheets("Sheet1").Select
Range("A1").Select
ActiveCell.Offset(0, 1).Value = Keytocompare2
ActiveCell.Offset(0, 2).Value = Keytocompare3
ActiveCell.Offset(0, 3).Value = Keytocompare4
ActiveCell.Offset(0, 4).Value = Keytocompare5
ActiveCell.Offset(0, 5).Value = "No Change"
Else
Windows("Output.xlsx").Activate
Sheets("Sheet1").Select
Range("A1").Select
ActiveCell.Offset(0, 1).Value = Keytocompare2
ActiveCell.Offset(0, 2).Value = Keytocompare3
ActiveCell.Offset(0, 3).Value = Keytocompare4
ActiveCell.Offset(0, 4).Value = Keytocompare5
ActiveCell.Offset(0, 5).Value = "Change"
End If
Else
Windows("Output.xlsx").Activate
Sheets("Sheet1").Select
Range("A1").Select
ActiveCell.Offset(0, 1).Value = Keytocompare2
ActiveCell.Offset(0, 2).Value = Keytocompare3
ActiveCell.Offset(0, 3).Value = Keytocompare4
ActiveCell.Offset(0, 4).Value = Keytocompare5
ActiveCell.Offset(0, 5).Value = "New Record"
End If
Windows("Yesterday.xlsx").Activate
Sheets("Sheet1").Select
' Range("A2").Select
ActiveCell.Offset(1, 0).Select
Loop
Windows("Today.xlsx").Activate
Sheets("Sheet1").Select
' Range("A2").Select
ActiveCell.Offset(1, 0).Select
Loop
End Sub
Could you guys help out in correcting this ?
give this a try
'ASSUMPTIONS:
'Data begins in cell A1 of each worksheet
'Data is continuous (does not have blank rows or columns)
'Comparison Key should be in column A of each sheet and should NEVER be blank
Sub CompareArrays()
' Sheet1.Cells.ClearContents ' *********** UNKNOWN SHEET
Dim filePick As FileDialog ' set up filePicker object
Set filePick = Application.FileDialog(msoFileDialogFilePicker)
filePick.AllowMultiSelect = False
MsgBox "Select Today's Common Customer File"
filePick.Title = "SELECT BOOK ONE"
filePick.Show
Dim todayBookName As String
todayBookName = filePick.SelectedItems(1)
MsgBox "Select Yesterday's Common Customer File"
filePick.Title = "SELECT BOOK TWO"
filePick.Show
Dim yesterBookName As String
yesterBookName = filePick.SelectedItems(1)
MsgBox "Select Output Common Customer File"
filePick.Title = "SELECT BOOK THREE"
filePick.Show
Dim outputBookName As String
outputBookName = filePick.SelectedItems(1)
Set filePick = Nothing
Dim todayBook As Workbook
todayBook = Application.Workbooks.Open(todayBookName)
Dim yesterBook As Workbook
yesterBook = Application.Workbooks.Open(yesterBookName)
Dim outputBook As Workbook
outputBook = Application.Workbooks.Open(outputBookName)
' -------------------- process workbooks -----------------
Dim recordStatus As String
Dim yesterCell As Range
Dim outputCell As Range
Dim keyToCompare As Variant
Dim i As Integer
Dim todayCell As Range
Set todayCell = todayBook.Sheets("Sheet1").Range("A1") ' set pointer to cell A1
Do While todayCell.Value <> ""
keyToCompare = todayCell.Resize(1, 6).Value ' copy row of cells ... one extra cell at end
keyToCompare = Application.Transpose(keyToCompare) ' convert to
keyToCompare = Application.Transpose(keyToCompare) ' single dimension array
Set yesterCell = yesterBook.Sheets("Sheet1").Range("A1") ' set pointer to cell A1
Do While yesterCell.Value <> "" ' process all non-blank cells
Set outputCell = outputBook.Sheets("Sheet1").Range("A1") ' set pointer to cell A1
If yesterCell.Value = keyToCompare(1) Then
If ( _
(yesterCell.Offset(0, 1).Value = keyToCompare(2)) _
And (yesterCell.Offset(0, 2).Value = keyToCompare(3)) _
And (yesterCell.Offset(0, 3).Value = keyToCompare(4)) _
And (yesterCell.Offset(0, 4).Value = keyToCompare(5))) Then
recordStatus = "No Change"
Else
recordStatus = "Change"
End If
Else
recordStatus = "New Record"
End If
keyToCompare(6) = recordStatus
For i = 1 To 5 ' update 5 cells in output workbook
outputCell.Offset(0, i).Value = keyToCompare(i + 1)
Next i
Set yesterCell = yesterCell.Offset(1, 0) ' move pointer one cell down
Set outputCell = outputCell.Offset(1, 0) ' this is missing from original code
Loop
Set todayCell = todayCell.Offset(1, 0)
Loop
End Sub
I put together a sample VBA code (tested also) assuming all 3 sheets are in current workbook. You can make necessary changes and adjustments to set to your workbooks and worksheets. I have used combination of Excel Formulas and 2 dimensional Arrays to read data from Excel and write back to Excel. Keep in mind, when you read from Excel into 2-d array, lower bound of array is 1, but when you write back to Excel you would need to initiate 0 based array (both for rows and columns).
Public Sub CompareSheets()
Dim wb As Workbook, xlRng As Range
Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet
Dim Ar1, Ar2, Ar3, ArLoad()
Dim lstR1!, lstR2!, iRow!, nRow!, str1$, str2$
Set wb = ThisWorkbook
Set ws1 = wb.Sheets(1): Set ws2 = wb.Sheets(2): Set ws3 = wb.Sheets(3)
' Get the last non blank cell in Column A in 1st and 2nd worksheets
Set xlRng = ws3.Cells(1, 1)
With xlRng
.FormulaR1C1 = "=MAX((" & ws1.Name & "!C1<>"""")*(ROW(" & ws1.Name & "!C1)))"
.FormulaArray = .Formula: .Calculate: lstR1 = .Value2
.FormulaR1C1 = "=MAX((" & ws2.Name & "!C1<>"""")*(ROW(" & ws2.Name & "!C1)))"
.FormulaArray = .Formula: .Calculate: lstR2 = .Value2
.Clear
End With
' Load into 2-d array data 1st and 2nd sheets
Ar1 = ws1.Range("A1:E" & lstR1).Value
Ar2 = ws2.Range("A1:E" & lstR2).Value
' Load Row number of 1st sheet that matches current row of second sheet
Set xlRng = ws3.Range("A1:A" & lstR2)
With xlRng
.FormulaR1C1 = "=IFERROR(MATCH(" & ws2.Name & "!RC," & ws1.Name & "!C,0),0)"
.Calculate: Ar3 = .Value: .Clear
End With
ReDim Preserve ArLoad(lstR2 - 1, 5) ' this is the array that will be loaded into 3rd worksheet
For iRow = 1 To UBound(Ar3, 1)
For nCol = 1 To 5
ArLoad(iRow - 1, nCol - 1) = Ar2(iRow, nCol) ' Load ArLoad with data from ws2
Next nCol
' Load Last Column of ArLoad with respective value depending if there is a change o
If Ar3(iRow, 1) > 0 Then
nRow = Ar3(iRow, 1) ' matching row number of 1st worksheet
str2 = Ar2(iRow, 2) & Ar2(iRow, 3) & Ar2(iRow, 4) & Ar2(iRow, 5)
str1 = Ar1(nRow, 2) & Ar1(nRow, 3) & Ar1(nRow, 4) & Ar1(nRow, 5)
If str1 = str2 Then
ArLoad(iRow - 1, 5) = "NO CHANGE"
Else
ArLoad(iRow - 1, 5) = "CHANGED"
End If
Else
ArLoad(iRow - 1, 5) = "NEW RECORD"
End If
Next iRow
ws3.Range("A1:F" & lstR2).Value = ArLoad
End Sub
I wanted to have a code wherein there will be an error or prompt in the userform if the cell in the sheet- wherein the data will be transferred, already has content. As of now, the code I'm using doesn't show any prompt but it succeeds in not updating the cell if a data is to be transferred to it again.
Private Sub CancelButton_Click()
Unload Me
End Sub
Private Sub ClearButton_Click()
Call UserForm_Initialize
End Sub
Private Sub OKButton_Click()
Dim emptyRow As Long
'Make Sheet1 active
Sheet1.Activate
'Determine emptyRow
Dim rFound As Range: Set rFound = Range("B:B").Find(BarcodeTextBox.Value, , , xlWhole)
If rFound Is Nothing Then
emptyRow = Range("B" & Rows.Count).End(xlUp).Row + 1
Else
emptyRow = rFound.Row
End If
'Transfer information
If TimeOptionButton1.Value = True Then
Cells(emptyRow, 5).Value = "Yes"
End If
If TimeOptionButton2.Value = True Then
Cells(emptyRow, 7).Value = "Yes"
End If
If BreakOptionButton1.Value = True Then
Cells(emptyRow, 9).Value = "Yes"
End If
If BreakOptionButton2.Value = True Then
Cells(emptyRow, 11).Value = "Yes"
End If
If BreakOptionButton3.Value = True Then
Cells(emptyRow, 14).Value = "Yes"
End If
If BreakOptionButton4.Value = True Then
Cells(emptyRow, 16).Value = "Yes"
End If
Cells(emptyRow, 2).Value = BarcodeTextBox.Value
Set ws = ActiveSheet
Me.TextBox1 = Application.WorksheetFunction. _
CountIf(ws.Range("$T$2:$E$977"), "IN")
Me.TextBox2 = Application.WorksheetFunction. _
CountIf(ws.Range("$U$2:$U$977"), "LF")
Me.TextBox3 = Application.WorksheetFunction. _
CountIf(ws.Range("$U$2:$U$977"), "READYMAN")
Me.TextBox4 = Application.WorksheetFunction. _
CountIf(ws.Range("$U$2:$U$977"), "B-MIRK")
Me.TextBox5 = Application.WorksheetFunction. _
CountIf(ws.Range("$U$2:$U$977"), "VISITOR")
End Sub
Private Sub UserForm_Initialize()
'Set Time In as default
TimeOptionButton1.Value = True
'Empty BarcodeTextBox
BarcodeTextBox.Value = ""
Set ws = ActiveSheet
Me.TextBox1 = Application.WorksheetFunction. _
CountIf(ws.Range("$T$2:$E$977"), "IN")
Me.TextBox2 = Application.WorksheetFunction. _
CountIf(ws.Range("$U$2:$U$977"), "LF")
Me.TextBox3 = Application.WorksheetFunction. _
CountIf(ws.Range("$U$2:$U$977"), "READYMAN")
Me.TextBox4 = Application.WorksheetFunction. _
CountIf(ws.Range("$U$2:$U$977"), "B-MIRK")
Me.TextBox5 = Application.WorksheetFunction. _
CountIf(ws.Range("$U$2:$U$977"), "VISITOR")
End Sub
Thank you in advance!
Concerning your code, I think that you may add something like this:
If TimeOptionButton1.Value = True Then
if len(cells(emptyRow,5)) = 0 then
MsgBox "Write Error Message here"
else
Cells(emptyRow, 5).Value = "Yes"
end if
End If
For each yes. You may consider building a separate function/sub later to avoid repetition.
This is my desired flow:
On "Sheet2" you can select a macro "Search by first name"
You see a popup to enter a name, you enter a name (X) and select ok
It will search the next sheet, "Master", and look for results where first name = X
and finally return these results back on "Sheet2"
Here's a screenshot of the two sheets:
Sheet 2
and
Master
The following VB code means that it only returns 1 result when there should be multiple sometimes:
Sub Searchbyfirstname()
Dim wks As Excel.Worksheet
Dim rCell As Excel.Range
Dim fFirst As String
Dim i As Long
Dim MyVal As String
MyVal = InputBox("Enter the first name of the employees record you need", "Search By First Name", "")
If MyVal = "" Then Exit Sub
Application.ScreenUpdating = False
Application.DisplayAlerts = False
With Cells(5, 1)
.Value = "The below data has been found for " & MyVal & ":"
.EntireColumn.AutoFit
.HorizontalAlignment = xlCenter
End With
i = 2
For Each wks In ActiveWorkbook.Worksheets
If wks.Name <> "List" Then
With wks.Range("B:B")
Set rCell = .Find(MyVal, , , xlWhole, xlByColumns, xlNext, False)
If Not rCell Is Nothing Then
fFirst = rCell.Address
Do
rCell.Hyperlinks.Add Cells(6, 1), "", "'" & wks.Name & "'!" & rCell.Address
wks.Range("A" & rCell.Row & ":Z" & rCell.Row).Copy Destination:=Cells(6, 1)
Set rCell = .FindNext(rCell)
i = i + 3
Loop While Not rCell Is Nothing And rCell.Address <> fFirst
End If
End With
End If
Next wks
Set rCell = Nothing
If i = 2 Then
MsgBox "No record for " & MyVal & " has been found", 64, "No Matches"
Cells(1, 1).Value = ""
End If
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Any help would be very much appreciated, thanks!
Ok so I am pretty sure I have the answer now that Maertin and chris neilsen pointed out the errors with hardcoding.
I have posted my code again but the points where I have added or changed are not code (didn't know the best way to format this):
Sub Searchbyfirstname()
Dim wks As Excel.Worksheet
Dim rCell As Excel.Range
Dim fFirst As String
Dim i As Long
Dim MyVal As String
MyVal = InputBox("Enter the first name of the employees record you need", "Search By First Name", "")
If MyVal = "" Then Exit Sub
Application.ScreenUpdating = False
Application.DisplayAlerts = False
With Cells(5, 1)
.Value = "The below data has been found for " & MyVal & ":"
.EntireColumn.AutoFit
.HorizontalAlignment = xlCenter
End With
i = 2
For Each wks In ActiveWorkbook.Worksheets
If wks.Name <> "List" Then
With wks.Range("B:B")
Set rCell = .Find(MyVal, , , xlWhole, xlByColumns, xlNext, False)
If Not rCell Is Nothing Then
fFirst = rCell.Address
Dim x As Integer
x = 6
With Sheets("Sheet2")
.Rows(6 & ":" & .Rows.Count).Delete
End With
' for this part I have created the variable x, then I'm assigning this 6 because that's the first row I want to put the data in, then I am saying if there's anything in row 6 or below, delete it
Do
rCell.Hyperlinks.Add Cells(x, 1), "", "'" & wks.Name & "'!" & rCell.Address
'see this and row below, instead of being Cells(6, 1), it is now x and this means it will paste to 6, then if there's another 7 and so on
wks.Range("A" & rCell.Row & ":Z" & rCell.Row).Copy Destination:=Cells(x, 1)
Set rCell = .FindNext(rCell)
i = i + 3
x = x + 1
' Here I am incrementing x by 1 so that if there's another piece of data to paste it will paste in the next row - on first go this would be row 7
Loop While Not rCell Is Nothing And rCell.Address <> fFirst
End If
End With
End If
Next wks
Set rCell = Nothing
If i = 2 Then
MsgBox "No record for " & MyVal & " has been found", 64, "No Matches"
Cells(1, 1).Value = ""
With Sheets("Sheet2")
.Rows(5 & ":" & .Rows.Count).Delete
End With
End If
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
Hi I have a VB linking to my Excel sheet done by the previous IT guy. Now its showing error "End If without Block If". Please help me debug. Codes below. Thank you all.
Private EditingRow As String
Private gCurrentStatus As String
Private gLocation As String
Private gRack As String
Private Sub cboType_Change()
cboSerialNo.Clear
Application.ScreenUpdating = False
Sheets("SGS Cylinder List").Select
ActiveSheet.Unprotect
ActiveSheet.UsedRange.Select
Selection.Sort Key1:=Range("D1"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
Set rng = Columns("D")
txtTotalSelectedType.Value = WorksheetFunction.countIF(rng, cboType.Value)
''' List all the selected Serial No
firstRowfound = False
firstrow = 0
lastRow = 0
Range("D1").Select
Do Until ActiveCell.Value = ""
If (firstRowfound = False And Cells(ActiveCell.Row, 4).Value = cboType.Value) Then
'MsgBox "1st row =" & ActiveCell.Row
firstrow = ActiveCell.Row
firstRowfound = True
End If
If (firstRowfound) Then
cboSerialNo.AddItem Trim(Cells(ActiveCell.Row, 3).Value) & " ," & Trim(Cells(ActiveCell.Row, 11))
End If
If (firstRowfound And Cells(ActiveCell.Row + 1, 4).Value <> cboType.Value) Then
'MsgBox "last row =" & ActiveCell.Row
lastRow = ActiveCell.Row
lastRowFound = True
Exit Do
End If
ActiveCell.Offset(1, 0).Select
Loop
If (firstrow > 0) Then
Set rngSelectedStatus = Range("I" & firstrow & ":I" & lastRow)
txtTotalCylinderAvailable.Value = WorksheetFunction.countIF(rngSelectedStatus, "Available")
Else
txtTotalCylinderAvailable.Value = 0
End If
ActiveSheet.Protect
Application.ScreenUpdating = True
End Sub
Private Sub cmdAdvancedAnalysis_Click()
If cboType.Value = "" Then
Exit Sub
End If
Worksheets("SGS Cylinder List").Select
ActiveSheet.Unprotect
newAddr = Sheets("SGS Cylinder List").[A2].CurrentRegion.Address(ReferenceStyle:=xlR1C1)
Sheets("Advanced").PivotTableWizard SourceType:=xlDatabase, SourceData:="SGS Cylinder List!" & newAddr
Sheets("Advanced").PivotTables("PivotTable1").RefreshTable
' Filter the PivotTable with the new Cylinder Type
Sheets("Advanced").PivotTables("PivotTable1").PageFields("Type").CurrentPage = cboType.Value
End Sub
Private Sub cmdCreateCylinder_Click()
Dim form1 As frmCylinder
Set form1 = New frmCylinder
form1.Show
End Sub
Private Sub cmdDisposalDate_Click()
Dim form1 As frmSelectDate
Set form1 = New frmSelectDate
form1.Show
Me.txtRsltDisposalDate = form1.SelectedDate
End Sub
Private Sub cmdLastUpdate_Click()
Dim form1 As frmSelectDate
Set form1 = New frmSelectDate
form1.Show
Me.txtLastUpdate.Value = form1.SelectedDate
End Sub
Private Sub cmdSearch_Click()
Sheets("SGS Cylinder List").Select
Range("C2").Select
Debug.Print cboSerialNo.Value
If cboSerialNo.Value = "" Then
Exit Sub
End If
cmdUpdate.Enabled = True
Do Until ActiveCell.Value = ""
' Found the row contains this given Serial No
''' to check the cboSerialNo first
serialNo = Left(cboSerialNo.Value, InStr(cboSerialNo.Value, ",") - 2)
If CStr(ActiveCell.Value) = serialNo Then
EditingRow = ActiveCell.Row
ActiveCell.EntireRow.Select
''' Show Selection
' Populate Location List
cboLocation.Clear
Sheets("Location").Select
Range("A2").Select
Do Until ActiveCell.Value = ""
cboLocation.AddItem ActiveCell.Value
ActiveCell.Offset(1, 0).Select
If CStr(ActiveCell.Value) = serialNo Then
EditingRow = ActiveCell.Row
ActiveCell.EntireRow.Select
cboRack.Clear
Sheets("Location").Select
Range("B2").Select
Do Until ActiveCell.Value = ""
cboRack.AddItem ActiveCell.Value
ActiveCell.Offset(1, 0).Select
Loop
End If
Sheets("SGS Cylinder List").Select
If (Cells(ActiveCell.Row, 1).Value <> "") Then
cboLocation.Value = Cells(ActiveCell.Row, 1).Value
End If
If (Cells(ActiveCell.Row, 1).Value <> "") Then
cboRack.Value = Cells(ActiveCell.Row, 1).Value
End If
txtRsltClientName.Value = Cells(ActiveCell.Row, 5).Value
txtRsltWell.Value = Cells(ActiveCell.Row, 6).Value
txtRsltJobID.Value = Cells(ActiveCell.Row, 7).Value
''' Populate Sample Type List
cboRsltSampleType.Clear
Set sampleTypeList = Range("SampleTypes")
For Each cell In sampleTypeList
cboRsltSampleType.AddItem cell.Value
Next
If (Cells(ActiveCell.Row, 8).Value <> "") Then
cboRsltSampleType.Value = Cells(ActiveCell.Row, 8).Value
End If
txtRsltDisposalDate.Value = Cells(ActiveCell.Row, 9).Value
' Set Existing Cylinder Status
cboRsltCylinderStatus.Clear
Set statusList = Range("StatusTypes")
For Each cell In statusList
cboRsltCylinderStatus.AddItem cell.Value
Next
If (Cells(ActiveCell.Row, 10).Value <> "") Then
cboRsltCylinderStatus.Value = Cells(ActiveCell.Row, 10).Value
End If
''' Save Current Row of Cylinder Data to Global variables
gLocation = Cells(ActiveCell.Row, 1).Value
gRack = Cells(ActiveCell.Row, 2).Value
gClientName = Cells(ActiveCell.Row, 5).Value
gWell = Cells(ActiveCell.Row, 6).Value
gJobID = Cells(ActiveCell.Row, 7).Value
gSampleType = Cells(ActiveCell.Row, 8).Value
gCurrentStatus = Cells(ActiveCell.Row, 10).Value
Exit Sub
End If
ActiveCell.Offset(1, 0).Select
Loop
End Sub
Private Sub cmdUpdate_Click()
''' 1. Save the current setting to a History Sheet if found changes made
''' 2. Update the current row
'' if any property of the Cylinder change
If ((gCurrentStatus <> cboRsltCylinderStatus.Value _
Or gLocation <> cboLocation.Value _
Or gWell <> txtRsltWell.Value _
Or gJobID <> txtRsltJobID.Value _
Or gSampleType <> cboRsltSampleType.Value) _
And EditingRow <> "") Then
Range("LastUpdateDate").Value = Date
Sheets("SGS Cylinder List").Select
ActiveSheet.Unprotect
' Copy that edited range
Range("A" & EditingRow & ":I" & EditingRow).Select
Selection.Copy
'' Check if Cylinder Status change
If gCurrentStatus <> cboRsltCylinderStatus.Value Then
Sheets("History List").Select
Range("A" & ActiveSheet.Rows.Count).End(xlUp).Select
ActiveCell.Offset(1, 0).Select
ActiveSheet.Paste
' Add a Current Status
Cells(ActiveCell.Row, 10).Value = cboRsltCylinderStatus.Value
' Add a Modified Date
If txtLastUpdate = "" Then
txtLastUpdate = Date
End If
Cells(ActiveCell.Row, 11).Value = txtLastUpdate
Cells(ActiveCell.Row, 11).NumberFormat = "dd-mmm-yy"
''' End of Step 1
End If
''' Start updating new changes
Sheets("SGS Cylinder List").Select
''' Add a New Location
If (txtRsltLocation.Value <> "" And cboLocation.Value = "") Then
Sheets("Location").Select
Range("A" & ActiveSheet.Rows.Count).End(xlUp).Select
ActiveCell.Offset(1, 0).Select
ActiveCell.Value = txtRsltLocation.Value
Sheets("SGS Cylinder List").Select
Cells(EditingRow, 1).Value = txtRsltLocation.Value
Else
Cells(EditingRow, 1).Value = cboLocation.Value
End If
Cells(EditingRow, 5).Value = txtRsltClientName.Value
Cells(EditingRow, 6).Value = txtRsltWell.Value
Cells(EditingRow, 7).Value = txtRsltJobID.Value
Cells(EditingRow, 8).Value = cboRsltSampleType.Value
Cells(EditingRow, 9).Value = txtRsltDisposalDate.Value
Cells(EditingRow, 10).Value = cboRsltCylinderStatus.Value
End If
''' Reset
cboRsltCylinderStatus.Value = ""
cboLocation.Value = ""
txtRsltClientName.Value = ""
txtRsltWell.Value = ""
txtRsltJobID.Value = ""
cboRsltSampleType.Value = ""
txtRsltDisposalDate.Value = ""
cboRsltCylinderStatus.Value = ""
End Sub
Private Sub ComboBox1_Change()
End Sub
Private Sub UserForm_Initialize()
Set typeList = Range("CylinderTypes")
For Each cell In typeList
cboType.AddItem cell.Value
Next
End Sub
Any help is much appreciated. Thank you
End If
ActiveCell.Offset(1, 0).Select
Loop
The End If at the beginning there is the cause of the error because it doesn't correspond to an opening If statement. Did you mean to put an Else If earlier in your code?
Update: I see this code:
Do Until ActiveCell.Value = ""
cboLocation.AddItem ActiveCell.Value
ActiveCell.Offset(1, 0).Select
There is no corresponding Loop keyword, and it's in the same scope as the End If I mentioned above, it's possible this is throwing the VBA interpreter/compiler off, but don't you have any detailed error messages with line-numbers or anything?
I think it's here .. in your Private Sub cmdSearch_Click()
cboLocation.Clear
Sheets("Location").Select
Range("A2").Select
Do Until ActiveCell.Value = "" '-------> You dont have 'Loop'
I have Excel sheets that will have data from many sources that will be grouped together so that what needs to be looked upon is above what you are looking from so there will be many VLookups on separate portions of one sheet.
Sub linkFDCfdv()
Range("A1").Select
Dim doesFDChaveDescription As Boolean
Dim isLastRowFDC As Boolean
Dim myRange As String
Dim firstFDCrow As Long
Dim lastFDCrow As Long
While Len(Selection.Value) > 0
If Selection.Value = "FDC" Then
If isLastRowFDC = False Then
firstFDCrow = ActiveCell.Row
End If
isLastRowFDC = True
ActiveCell.Offset(0, 3).range("A1").Select
If Len(Selection.Value) > 0 Then
doesFDChaveDescription = True
Else
doesFDChaveDescription = False
End If
ActiveCell.Offset(0, -3).range("A1").Select
Else
If isLastRowFDC = True Then
lastFDCrow = ActiveCell.Row - 1
End If
End If
If Selection.Value = "FDV" Then
ActiveCell.Offset(0, 10).range("A1").Select
myRange = "B" & firstFDCrow & ":D" & lastFDCrow
ActiveCell.Formula = "=VLOOKUP(R[0]C[-2]," & myRange & ",2)"
ActiveCell.Offset(0, -10).range("A1").Select
End If
ActiveCell.Offset(1, 0).range("A1").Select
Wend
End Sub
What's happening is that my macro makes the formula:
=VLOOKUP(I9,'B3':'D8',2)
If I take out the ' marks the macro works perfectly.
That is because you are using a mix of R1C1 style with A1 style. Is this what you are trying?
ActiveCell.Formula = "=VLOOKUP(" & ActiveCell.Offset(,-2).Address & _
"," & myRange & ",2)"