This code was working about a month ago with out any issues.
The run time error (#13) points to:
lastRow = Application.Match(campus, subject.Range("A1:A35000"), 1) + 2
I have run the macro a few times with it being partially successful some times. Other times it does not get any data at all.
If the macro is partially successful, what would cause the type mismatch if the data in the columns is the same through out. All the data exported from SQL Tools and then copied and pasted to the worksheets.
Dim lastRow As Long
Dim firstRow As Long
Dim count As Long
Dim campus As String
Dim gradeCount As Integer
Dim current As String
Dim previous As String
campus = schools.Range("A" & i).Value
With subject.Range("A:A")
Set Rng = .Find(what:=campus, _
After:=.Cells(.Cells.count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
searchorder:=xlByRows, _
searchdirection:=xlNext, _
MatchCase:=False)
gradeCount = 0
firstRow = 0
If Not Rng Is Nothing Then
firstRow = Application.Match(campus, subject.Range("A1:A35000"), 0) + 2
lastRow = Application.Match(campus, subject.Range("A1:A35000"), 1) + 2
gs.Range("A" & rowCount).Value = schools.Range("A" & i).Value
gs.Range("C" & rowCount).Value = schools.Range("C" & i).Value
currentCampus = gs.Range("A" & rowCount).Value
current = ""
previous = ""
For count = firstRow To lastRow
If campus = subject.Range("A" & count).Value Then
current = subject.Range("C" & count)
gs.Range("A" & rowCount).Value = schools.Range("A" & i).Value
If current <> previous Then
gs.Range("C" & rowCount).Value = schools.Range("C" & i).Value
gs.Range("D" & rowCount).Value = grade
gs.Range("E" & rowCount).Value = current
previous = current
gradeCount = gradeCount + 1
rowCount = rowCount + 1
End If
End If
Next count
If gradeCount > 1 Then
gs.Range("D" & rowCount).Value = grade
gs.Range("E" & rowCount).Value = "*"
gs.Range("C" & rowCount).Value = schools.Range("C" & i).Value
rowCount = rowCount + 1
End If
End If
End With
This is an indication that the Match failed to find a value.
If the same formula occupied a worksheet cell, you would see:
#N/A
Related
All,
I have the below code which iterates through columns and rows to see IF the statement is true. It seems to be running through the whole code bringing back duplicate rows. I would like this code to go to the next row once a value has been found.
I'm unsure how to adapt this code but I imagine the issue lies with the general for each loop I have set up any advise on how to fix this would be much appreciated.
Dim LR As Long
LR = Workbooks(trackerName).Sheets("Results").Range("A1048576").End(xlUp).Row
Dim LRC As Long
LRC = Workbooks(trackerName).Sheets("Columnsforbox").Range("A1048576").End(xlUp).Row + 1
For Each c In Workbooks(trackerName).Sheets("results").Range("A4:K" & LR)
If c.Value = UserName Or c.Value = UserId Then
Worksheets("Columnsforbox").Range("A" & LRC) = Worksheets("Results").Range("E" & c.Row)
Worksheets("Columnsforbox").Range("B" & LRC) = Worksheets("Results").Range("D" & c.Row)
Worksheets("Columnsforbox").Range("C" & LRC) = Worksheets("Results").Range("A" & c.Row)
Worksheets("Columnsforbox").Range("D" & LRC) = Worksheets("Results").Range("B" & c.Row)
Worksheets("Columnsforbox").Range("E" & LRC) = Worksheets("Results").Range("C" & c.Row)
LRC = LRC + 1
End If
Next c
Basicly the same, but now we loop through array:
Dim myArr(), i as Long, j as Long
Dim LR As Long
LR = Workbooks(trackerName).Sheets("Results").Range("A1048576").End(xlUp).Row
Dim LRC As Long
LRC = Workbooks(trackerName).Sheets("Columnsforbox").Range("A1048576").End(xlUp).Row + 1
myArr = Range("A4:K" & LR).Value
For i = LBound(myArr,1) To Ubound(myArr,1)
For j = LBound(myArr,2) To Ubound(myArr,2)
If myArr(i,j) = UserName Or myArr(i,j) = UserId Then
Worksheets("Columnsforbox").Range("A" & LRC) = Worksheets("Results").Range("E" & i)
Worksheets("Columnsforbox").Range("B" & LRC) = Worksheets("Results").Range("D" & i)
Worksheets("Columnsforbox").Range("C" & LRC) = Worksheets("Results").Range("A" & i)
Worksheets("Columnsforbox").Range("D" & LRC) = Worksheets("Results").Range("B" & i)
Worksheets("Columnsforbox").Range("E" & LRC) = Worksheets("Results").Range("C" & i)
LRC = LRC + 1
Exit For
End If
Next j
Next i
Well, you got an idea.
Another solution without using loop.
Sub Demo()
Dim rngUserName As Range, rngUserId As Range
Dim LR As Long, LRC As Long, rowIndex As Long
Dim srcSht As Worksheet, destSht As Worksheet
Set srcSht = Workbooks(trackerName).Sheets("Results") 'this is source sheet
Set destSht = Workbooks(trackerName).Sheets("Columnsforbox") 'this is destination sheet
LR = srcSht.Cells(srcSht.Rows.Count, "A").End(xlUp).Row 'get last row using column A
LRC = destSht.Cells(destSht.Rows.Count, "A").End(xlUp).Row 'get last row using column A
Set rngUserName = Range("A4:K" & LR).Find(UserName, after:=Cells(4, 1), searchdirection:=xlPrevious) 'find user name
Set rngUserId = Range("A4:K" & LR).Find(UserId, after:=Cells(4, 1), searchdirection:=xlPrevious) 'find user id
If Not rngUserName Is Nothing And Not rngUserId Is Nothing Then 'if both user name & user id are found
rowIndex = Application.Max(rngUserName.Row, rngUserId.Row)
ElseIf Not rngUserName Is Nothing Then 'if only user name found
rowIndex = rngUserName.Row
ElseIf Not Not rngUserId Is Nothing Then 'if only user id found
rowIndex = rngUserId.Row
End If
MsgBox rowIndex
destSht.Range("A" & LRC) = srcSht.Range("E" & rowIndex)
destSht.Range("B" & LRC) = srcSht.Range("D" & rowIndex)
destSht.Range("C" & LRC) = srcSht.Range("A" & rowIndex)
destSht.Range("D" & LRC) = srcSht.Range("B" & rowIndex)
destSht.Range("E" & LRC) = srcSht.Range("C" & rowIndex)
End Sub
First of all i'm just a beginner in VBA and I'm Stuck in the middle and couldn't find a possible way out. To be precise on my requirement, Attached below is the Snapshot of the data which i have currently. In the Date Range column i would need a date range based on the Dates available in each invoices. If a continuity breaks in the dates i would need the dates separated by comma which is shown in the sample data. Below is my piece of code which arrives only the dates and couldn't form a date range. Hope i can find my way out and would be earning something new out of this :-) Thanks!]1
Sub DD()
With Application
.ScreenUpdating = False
.DisplayAlerts = False
.EnableCancelKey = False
.EnableEvents = False
End With
Sheets("Claim Lines").Select
ActiveWorkbook.Worksheets("Claim Lines").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Claim Lines").Sort.SortFields.Add Key:=Range("B1"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortTextAsNumbers
ActiveWorkbook.Worksheets("Claim Lines").Sort.SortFields.Add Key:=Range("D1"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortTextAsNumbers
With ActiveWorkbook.Worksheets("Claim Lines").Sort
.SetRange ActiveSheet.UsedRange
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Range("B2").Select
Do
If ActiveCell.Value = ActiveCell.Offset(1, 0).Value Then
StrtRow = 2
tmperow = ActiveSheet.UsedRange.Rows.Count
For j = 0 To Application.WorksheetFunction.CountIf(Range("B" & StrtRow & ":B" & tmperow), ActiveCell.Value) - 1
If j = 0 Then
DOS = CDate(Cells(ActiveCell.Offset(0, 2).Row + j, "D").Value)
ElseIf j = Application.WorksheetFunction.CountIf(Range("B" & StrtRow & ":B" & tmperow), ActiveCell.Value) - 1 Then
ElseIf DOS = DOS Then
DOS = CDate(Cells(ActiveCell.Offset(0, 2).Row + j, "D").Value)
ElseIf j = Application.WorksheetFunction.CountIf(Range("B" & StrtRow & ":B" & tmperow), ActiveCell.Value) - 1 Then
ElseIf DOS = DOS Then
DOS = DOS & " & " & CDate(Cells(ActiveCell.Offset(0, 2).Row + j, "D").Value)
Else
DOS = DOS & ", " & CDate(Cells(ActiveCell.Row + j, "D").Value)
End If
Next
Range("N" & ActiveCell.Row).Value = DOS & " to " & DOS
DOS = ""
Else
Range("N" & ActiveCell.Row).Value = Range("D" & ActiveCell.Row).Value
End If
ActiveCell.Offset(1, 0).Select
Loop Until IsEmpty(ActiveCell.Value)
End Sub
I quickly wrote this. I am sure there can be better ways to achieve this but I could only spend this much time before I hit the sack :)
Sub Sample()
Dim ws As Worksheet
Dim dString As String, ss As String
Dim lRow As Long, i As Long
Dim sRow As Long, eRow As Long
Dim sDate As Date, eDate As Date
'~~> This is your worksheet which has data
Set ws = ThisWorkbook.Worksheets("Claim Lines")
'~~> Setting start row and end row for Col C
sRow = 2: eRow = 2
With ws
'~~> Sort Col A and B on Col A first and then on Col B
.Columns("A:B").Sort Key1:=.Range("A1"), Key2:=.Range("B1"), _
Order1:=xlAscending, Header:=xlYes, OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom, DataOption1:=xlSortNormal
'~~> Find Last Row of Col A
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Set the Initial Start Date and End Date
sDate = .Range("B2").Value: eDate = .Range("B2").Value
'~~> Loop through the data
For i = 2 To lRow
'~~> Check if the value of the current cell in Col A
'~~> is the same as the value in the next cell
If .Range("A" & i) = .Range("A" & i + 1) Then
'~~> Compare date values in Col B to check if they are in sequence
If .Range("B" & i + 1) - .Range("B" & i) = 1 Then
'~~> If yes then set it as new End Date
eDate = .Range("B" & i + 1)
Else
'~~> Get the string to be written in Col C
dString = GetDString(dString, sDate, eDate, .Range("B" & i))
'~~> Set New Start Date
sDate = .Range("B" & i + 1)
End If
Else
eRow = i
dString = GetDString(dString, sDate, eDate, .Range("B" & i))
.Range("C" & sRow & ":C" & eRow).Value = dString
dString = "": sRow = eRow + 1
sDate = .Range("B" & i + 1).Value
eDate = .Range("B" & i + 1).Value
End If
Next i
End With
End Sub
'~~> Function to get the string to be written in Col C
Private Function GetDString(s As String, StartDate As Date, _
endDate As Date, CurCell As Range) As String
If s = "" Then
If endDate = CurCell.Value Then
If StartDate = endDate Then
s = StartDate
Else
s = StartDate & "-" & endDate
End If
Else
s = (StartDate & "-" & endDate) & "," & CurCell.Value
End If
Else
If endDate = CurCell.Value Then
s = s & "," & StartDate & "-" & endDate
Else
s = s & "," & CurCell.Value
End If
End If
GetDString = s
End Function
ScreenShot of various tests
I'm trying to create a Macro that will modify contents in columns S, W and AH based on the content in AB
e.g. if AB1 = No, then S1=C-MEM, AH = N/A and W is cleared.
For some reason, I get a 'Type mismatch' error on the first line of my if statement and can't figure out why or how to fix it - even after reading other posts about similar issue.
Sub test()
Dim lastrow As Long
Dim i As Long
lastrow = Range("AB" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
**-> If Range("AB" & i).Value = "No" Then
Range("S" & i).Value = "C-MEM"
Range("W" & i).Value = ""
Range("AH" & i).Value = "N/A"
End If
Next i
End Sub
Thanks
You are trying to test if an error is = No.
Test for the error and skip the logic in that loop:
Sub test()
Dim lastrow As Long
Dim i As Long
lastrow = Range("AB" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
If Not IsError(Range("AB" & i).Value) Then
If Range("AB" & i).Value = "No" Then
Range("S" & i).Value = "C-MEM"
Range("W" & i).Value = ""
Range("AH" & i).Value = "N/A"
End If
End If
Next i
End Sub
As mentioned in the title, I need a VBA equivalent to the Excel Value function. My data set looks like this: Data set example
What I am looking for is VBA code equivalent to this: =Value(A2)+Value(B2). That would go in column C
The output must be the same as that function. For the given example, column C should end up looking like this: End product
More than that, it needs to only have the value in the cell after the macro is run, rather than displaying the value and still having that formula in it.
Here is what I have done so far:
For i = 1 To LastRow
strValue = Val(sht.Range("A" & i))
strValue1 = Val(sht.Range("B" & i))
sht.Range("C" & i).Value = strValue + strValue1
Next i
I also tried variations on this, a couple of which are shown below:
For i = 1 To LastRow
strValue = Evaluate(sht.Range("A" & i))
strValue1 = Evaluate(sht.Range("B" & i))
sht.Range("C" & i).Value = strValue + strValue1
Next i
For i = 1 To LastRow
strValue = sht.Range("A" & i)
strValue1 = sht.Range("B" & i)
strVal = Evaluate(strValue)
strVal1 = Evaluate(strValue1)
sht.Range("C" & i).Value = strVal + strVal1
Next i
I can't find anything that will work for me. The output in C for the example set ends up being just 9. Pretty sure it is taking the first number in A and adding it to the first number in B. So when the hour in B changes to 1 C displays 10.
I also tried simply:
For i=1 To LastRow
sht.Range("C" & i).Value = sht.Range("A" & i).Value + sht.Range("B" & i).Value
Next i
That just concatenated the text to the format 9/03/15 00:00:00
Any and all help appreciated. Bonus if you can point me in the right direction for changing the final C values from that number (ie. 42250.00017) to the custom date/time format 'yyyy-mm-dd hh:mm:ss'.
Edit: Here is my code up to the sticking point. Everything else works as I want it to, the only problem is with the last For loop.
Sub sbOrganizeData()
Dim i As Long
Dim k As Long
Dim sht As Worksheet
Dim LastRow As Long
Dim sFound As String
Dim rng As Range
Dim sheet As Worksheet
Dim Sheet2 As Worksheet
Dim strFile As String
Dim strCSV As String
Dim strValue As Double
Dim strValue1 As Double
Dim strVal As Long
Dim strVal1 As Long
Application.DisplayAlerts = False
Sheets("all016").Delete
Sheets("Sheet1").Delete
Application.DisplayAlerts = True
Set sheet = Sheets.Add
Set Sheet2 = Sheets.Add
sheet.Name = "all016"
Sheet2.Name = "Sheet1"
strFile = ActiveWorkbook.Path
strCSV = "*.csv"
sFound = Dir(strFile & "\*.csv")
If sFound <> "" Then
Workbooks.Open Filename:=strFile & "\" & sFound
End If
Range("A1").CurrentRegion.Copy Destination:=Workbooks("solar.xlsm").Sheets("all016").Range("A1")
Workbooks(sFound).Close
Set sht = ThisWorkbook.Sheets("all016")
LastRow = sht.Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row
sht.Range("C1").EntireColumn.Insert
For i = 1 To LastRow
'Code that doesn't quite work here'
sht.Range("C" & i).NumberFormat = "yyyy-mm-dd hh:mm:ss"
Next i
The issue is that the dates and times are strings so something like this will work:
For i = 2 To LastRow
strValue = Evaluate("VALUE(TRIM(" & sht.Range("A" & i).Address(1,1,,1) & "))")
strValue1 = Evaluate("VALUE(TRIM(" & sht.Range("B" & i).Address(1,1,,1) & "))")
sht.Range("C" & i).Value = strValue + strValue1
'the format
sht.Range("C" & i).NumberFormat = "mm/dd/yy hh:mm:ss"
Next i
You have to reference the .Value2 field of the range element as:
For i = 1 To LastRow
sht.Range("C" & i).Value2 = sht.Range("A" & i).Value2 + sht.Range("B" & i).Value2
Next i
The value is free of formatting and just in Excel's time/date code as you want your final result to be. Cheers,
I'm new to vba and trying to write a barcode scanner algorithm. It works fine right now but I want to keep serial numbers in my exel table and their structure has to be like "A151000". I want with each barcode entered a cell with an inputbox also be assigned to a serial number. for example when a new entry(Barcode) written in column C I want in column B serial numbers last digit increased by 1 and stored in that cell automatically.
Right now I can drag the cell from corner and exel increases the last digit. How can I trigger this with new entries automatically? Thanks in advance.
A151000
A151001
A151002
...
Sub DataInput()
Dim SearchTarget As String
Dim myRow As Long
Dim Rng As Range
Static PrevCell As Range
Dim FoundCell As Range
Dim CurCell As Range
Dim a As String
Dim Target As Range
Dim buttonclick As Boolean
V = True
If PrevCell Is Nothing Then
myRow = Selection.Row
Set PrevCell = Range("C" & myRow)
End If
Set Rng = Range("C:C,C:C") 'Columns for search defined here
With Rng
Set FoundCell = .Cells.Find(What:=SearchTarget, _
After:=PrevCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=True)
End With
Dim Eingabezahl As String
Do While Eingabezahl! = ""
Eingabezahl = InputBox("Last barcode scanned" & " " & Eingabezahl)
Range("C" & Range("C" & Rows.Count).End(xlUp).Row + 1) = Eingabezahl
Range("D" & Range("D" & Rows.Count).End(xlUp).Row + 1) = Now()
Range("E" & Range("E" & Rows.Count).End(xlUp).Row + 1) = "VALID"
Loop
End Sub
TO use the Autofill function and not change your original code you could just add in the autofill in your sub:
Dim Eingabezahl As String
Dim rngLastBCell As Range
Do While Eingabezahl = ""
Eingabezahl = InputBox("Last barcode scanned" & " " & Eingabezahl)
Set rngLastBCell = Range("B" & Rows.Count).End(xlUp)
rngLastBCell.AutoFill Destination:=Range(rngLastBCell, rngLastBCell.Offset(1)), Type:=xlFillDefault
Range("C" & Range("C" & Rows.Count).End(xlUp).Row + 1) = Eingabezahl
Range("D" & Range("D" & Rows.Count).End(xlUp).Row + 1) = Now()
Range("E" & Range("E" & Rows.Count).End(xlUp).Row + 1) = "VALID"
Loop
Or you could use the following that using the same concept (an autofill) but condenses al of your calls to the worksheet into a single line:
Dim Eingabezahl As String
Dim rngLastBCell As Range
Do While Eingabezahl = ""
Eingabezahl = InputBox("Last barcode scanned" & " " & Eingabezahl)
Set rngLastBCell = Range("B" & Rows.Count).End(xlUp)
rngLastBCell.AutoFill Destination:=Range(rngLastBCell, rngLastBCell.Offset(1)), Type:=xlFillDefault
rngLastBCell.Offset(1, 1).Resize(, 3) = Array(Eingabezahl, Now(), "VALID")
Loop
Although I would recommend just using appenending the current row to the end of your serial and not making as many calls to the worksheet by using an array:
Dim rngB As Range
Dim Eingabezahl As String
Dim SerialBase As String
SerialBase = "A15100"
Do While Eingabezahl = ""
Eingabezahl = InputBox("Last barcode scanned" & " " & Eingabezahl)
Set rngB = Range("B" & Rows.Count).End(xlUp).Offset(1)
rngB.Resize(, 4).Value = Array(SerialBase & rngB.Row, Eingabezahl, Now(), "VALID")
Loop