Related
first post and also new to VBA so I apologize for anything that is unclear. I have created a code to generate a daily printout of employees, equipment, and subcontractors. The loop is looking for "S" (subcontractors) each day. There is only one day where "S" is present and there are 4 on that day. The issue is that the loop begins correctly and populates the correct information when it finds "S" and lists the 4 separate subcontractors, but every day before and after that it continues to list the first subcontractor even though no "S" is found on those dates. How can I get it to clear that entry if no other "S" are found? I hope that makes sense and I have included the code. Thank you!
Screesnhot
Sub WriteReport_Click()
Dim EachName(1 To 5000) As Variant
Dim NameHours(1 To 5000) As Variant
Dim NamePhase(1 To 5000) As Variant
Dim EquipHours(1 To 5000) As Variant
Dim EquipPhase(1 To 5000) As Variant
Dim EachDate(1 To 5000) As Date
Dim EachEquip(1 To 5000) As Variant
Dim EachSub(1 To 5000) As Variant
Dim SubAmount(1 To 5000) As Variant
Dim i As Long 'loop through records
Dim k As Integer 'count employees
Dim h As Integer 'count equipment
Dim t As Integer 'count subcontractor
Dim m As Integer 'count dates
Dim j As Integer
Dim x As Integer
Dim lr, s, p, StartBorder, EndBorder As Integer 'keeps row counts Start & Finish
Dim TestString As String
Sheets("Data").Activate
k = 1 'counts EachName
h = 1 'counts EachEquip
t = 1 'counts EachSub
m = 1 'counts dates
lr = 1
p = 0
For i = 1 To Rows.Count
If Cells(i, 3) = "L" Then
EachName(1) = Cells(i, 11)
Exit For
End If
Next i
For i = 1 To Rows.Count
If Cells(i, 3) = "E" Then
EachEquip(1) = Cells(i, 12)
Exit For
End If
Next i
For i = 1 To Rows.Count
If Cells(i, 3) = "S" Then
EachSub(1) = Cells(i, 9)
Exit For
End If
Next i
NameHours(1) = 0
EquipHours(1) = 0
EachDate(1) = Cells(1, 1)
SubAmount(1) = 0
Dim LastRow As Integer
For i = 1 To 5000
If EachDate(m) <> Cells(i, 1) Then
m = m + 1 'setting array for next new date
EachDate(m) = Cells(i, 1)
lr = Sheets("Report").Cells(Rows.Count, 1).End(xlUp).Row + 1
StartBorder = lr
Sheets("Report").Cells(lr, 1) = Format(EachDate(m - 1), "mm/dd/yy") 'prints date
Sheets("Report").Cells(lr, 1).Interior.ColorIndex = 4 'highlights date
For j = 1 To k 'prints employees, hours and phase
Sheets("Report").Cells((lr + j), 1) = EachName(j)
Sheets("Report").Cells((lr + j), 2) = NameHours(j)
Sheets("Report").Cells((lr + j), 4) = NamePhase(j)
Sheets("Report").Cells((lr + j), 5).Formula = _
"=IF(A" & CStr(lr + j) & "<>"""",VLOOKUP(A" & CStr(lr + j) & ",Employee,2,FALSE),"""")"
Next j
k = 1
lr = Sheets("Report").Cells(Rows.Count, 1).End(xlUp).Row + 1
For s = i To 5000 'getting first employee for next date
If Cells(s, 1) = EachDate(m) And Cells(s, 3) = "L" Then
EachName(1) = Cells(s, 11)
Exit For
End If
Next s
Erase NameHours 'clearing manhours for next date
For j = 1 To h
Sheets("Report").Cells((lr + j), 1) = Trim(EachEquip(j))
Sheets("Report").Cells((lr + j), 3) = EquipHours(j)
Sheets("Report").Cells((lr + j), 4) = EquipPhase(j)
Sheets("Report").Cells((lr + j), 5).Formula = _
"=LEFT(IF(A" & CStr(lr + j) & "<>"""",VLOOKUP(A" & CStr(lr + j) & ",EquipList,2,FALSE),""""),20)"
Next j
h = 1
For s = i To 5000 'getting first equipment for next date
If Cells(s, 1) = EachDate(m) And Cells(s, 3) = "E" Then
EachEquip(1) = Cells(s, 12)
Exit For
End If
Next s
Erase EquipHours ' clearing equipment hours for next date
lr = Sheets("Report").Cells(Rows.Count, 1).End(xlUp).Row + 1
For x = 1 To t
Sheets("Report").Cells((lr + x), 1) = EachSub(x)
Sheets("Report").Cells((lr + x), 3) = SubAmount(x)
Next x
For x = i To 5000 'getting subcontractor for next date
If Cells(x, 1) = EachSub(m) And Cells(x, 3) = "S" Then
EachSub(1) = " "
Exit For
End If
Next x
EndBorder = lr + x
t = 1
With Worksheets("Report") 'draws borders
.Range(.Cells(StartBorder, 1), .Cells(EndBorder, 8)).BorderAround ColorIndex:=1, Weight:=xlThick
End With
End If
Select Case Cells(i, 3).Value
Case "L"
If Cells(i, 11) = EachName(k) Then
If Cells(i, 7) = 0 Then
p = p + 1 'adding up per diem
End If
NamePhase(k) = Cells(i, 2)
NameHours(k) = NameHours(k) + Cells(i, 7)
Else
k = k + 1
EachName(k) = Cells(i, 11)
NamePhase(k) = Cells(i, 2)
If Cells(i, 7) = 0 Then
p = p + 1
End If
NameHours(k) = NameHours(k) + Cells(i, 7)
End If
Case "E"
If Cells(i, 12) = EachEquip(h) Then
EquipPhase(h) = Cells(i, 2)
EquipHours(h) = EquipHours(h) + Cells(i, 7)
Else
h = h + 1
EachEquip(h) = Cells(i, 12)
EquipPhase(h) = Cells(i, 2)
EquipHours(h) = EquipHours(h) + Cells(i, 7)
End If
Case "S"
If Cells(i, 9) = EachSub(t) Then
EachSub(t) = Cells(i, 9)
SubAmount(t) = SubAmount(t) + Cells(i, 8)
Else
t = t + 1
EachSub(t) = Cells(i, 9)
SubAmount(t) = SubAmount(t) + Cells(i, 8)
End If
End Select
Next i
MsgBox "Report Completed !!!"
End Sub
You will find your code easier to debug/maintain if you separate the collection of the data and the report generation into 2 discrete steps, preferably in subroutines. For example
Option Explicit
Dim EachName(0 To 5000, 1 To 3) As Variant '1=name 2=hours 3=phase
Dim EachEquip(0 To 5000, 1 To 3) As Variant '1=name 2=hrs 3=phase
Dim EachSub(0 To 5000, 1 To 2) As Variant ' 1=name 2=amount
Dim k As Long 'count employees
Dim h As Long 'count equipment
Dim t As Long 'count subcontractor
Sub WriteReport_Click()
' specify book and sheets to process
Dim wb As Workbook, wsData As Worksheet, wsRep As Worksheet
Set wb = ThisWorkbook ' or ActiveWorkBook
' determine extent of data
Dim LastRow As Long, iRow As Long
Set wsData = wb.Sheets("Data")
LastRow = wsData.Cells(Rows.Count, 1).End(xlUp).Row
' clear report sheet
Set wsRep = wb.Sheets("Report")
wsRep.Cells.Clear
' scan data for first date
Dim RepDate As Date
RepDate = wsData.Cells(1, 1)
Call GetData(RepDate, wsData)
' scan data for more dates
For iRow = 1 To LastRow
If wsData.Cells(iRow, 1) <> RepDate Then
' report existing date
Call ReportData(RepDate, wsRep)
' get data for new date
RepDate = wsData.Cells(iRow, 1)
Call GetData(RepDate, wsData)
End If
Next
' report last date
Call ReportData(RepDate, wsRep)
'end
wsRep.Columns("A:E").AutoFit
MsgBox "Report Completed", vbInformation, LastRow & " rows scanned"
End Sub
Sub ReportData(d As Date, ws As Worksheet)
Debug.Print "ReportData", d
Dim lr As Long, StartBorder As Long, EndBorder As Long, j As Long
lr = ws.Cells(Rows.Count, 1).End(xlUp).Row + 1
StartBorder = lr
ws.Cells(lr, 1) = Format(d, "mm/dd/yy") 'prints date
ws.Cells(lr, 1).Interior.ColorIndex = 4 'highlights date
'prints employees, hours and phase
For j = 1 To k
ws.Cells((lr + j), 1) = EachName(j, 1) 'empoyee name
ws.Cells((lr + j), 2) = EachName(j, 2) 'hrs
ws.Cells((lr + j), 4) = EachName(j, 3) 'phase
ws.Cells((lr + j), 5).Formula = _
"=IF(A" & CStr(lr + j) & "<>"""",VLOOKUP(A" & CStr(lr + j) & ",Employee,2,FALSE),"""")"
Next j
' report equipment
lr = ws.Cells(Rows.Count, 1).End(xlUp).Row + 1
For j = 1 To h
ws.Cells((lr + j), 1) = EachEquip(j, 1) 'equip name
ws.Cells((lr + j), 3) = EachEquip(j, 2) 'hours
ws.Cells((lr + j), 4) = EachEquip(j, 3) 'phase
ws.Cells((lr + j), 5).Formula = _
"=LEFT(IF(A" & CStr(lr + j) & "<>"""",VLOOKUP(A" & CStr(lr + j) & ",EquipList,2,FALSE),""""),20)"
Next j
' report sub contractors
lr = ws.Cells(Rows.Count, 1).End(xlUp).Row + 1
For j = 1 To t
ws.Cells((lr + j), 1) = EachSub(j, 1) 'sub name
ws.Cells((lr + j), 3) = EachSub(j, 2) 'amount
Next j
' draws borders
EndBorder = ws.Cells(Rows.Count, 1).End(xlUp).Row
ws.Range(ws.Cells(StartBorder, 1), ws.Cells(EndBorder, 8)) _
.BorderAround ColorIndex:=1, Weight:=xlThick
End Sub
Sub GetData(d As Date, ws As Worksheet)
Debug.Print "GetData", d
Dim LastRow As Long, i As Long
LastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
' clear global arrays
Erase EachName
Erase EachEquip
Erase EachSub
k = 0: h = 0: t = 0
For i = 1 To LastRow
If ws.Cells(i, 1) = d Then
Select Case ws.Cells(i, 3)
Case "L" ' Employee
If ws.Cells(i, 11) <> EachName(k, 1) Then
k = k + 1
End If
EachName(k, 1) = ws.Cells(i, 11)
EachName(k, 2) = ws.Cells(i, 7) + EachName(k, 2) ' hours
EachName(k, 3) = ws.Cells(i, 2) ' phase
Case "E" ' Equipment
If ws.Cells(i, 12) <> EachEquip(h, 1) Then
h = h + 1
End If
EachEquip(h, 1) = Trim(ws.Cells(i, 12)) ' equip name
EachEquip(h, 2) = ws.Cells(i, 7) + EachEquip(h, 2) ' hours
EachEquip(h, 3) = ws.Cells(i, 2) ' phase
Case "S" ' Subcontractor
If ws.Cells(i, 9) <> EachSub(t, 1) Then
t = t + 1
End If
EachSub(t, 1) = ws.Cells(i, 9) ' sub name
EachSub(t, 2) = ws.Cells(i, 8) + EachSub(t, 2) ' amount
Case Else
MsgBox "Unknown code at row " & i, vbExclamation
End Select
End If
Next
End Sub
Could you please help me to solve the problem with the macro that is processed too slow?
I tried to change the range to just 3 rows and it was processed 1 minute while on the other computers it lasts just 20s for over 300 rows. Is it caused by the Excel update and the dynamic arrays? If yes, do you know how to fix it?
Sub import_new_forecast()
Dim lrow, lcol, i, j, k As Long
Dim USED_WB As Workbook
Dim fcst_file As Variant
Dim data_arr(), ldata_arr(), colmap_arr(), fhead_arr(), head_arr()
Dim ans As Variant
fcst_file = Application.GetOpenFilename(Filefilter:="XLS Files, *.xls", Title:="Provide RSM path", MultiSelect:=False)
Set USED_WB = Application.Workbooks.Open(fcst_file)
With USED_WB.ActiveSheet
lrow = .Cells(.Rows.Count, 1).End(xlUp).Row
Do Until CLng(.Cells(lrow, 2).Value) > 1 'Find last not empty row in RSM file
lrow = lrow - 1
Loop
lcol = .Cells(1, .Columns.Count).End(xlToLeft).Column
head_arr = Range(.Cells(1, 1), .Cells(1, lcol)).Value
data_arr = Range(.Cells(2, 1), .Cells(lrow, lcol)).Value
End With
With ThisWorkbook.Sheets("Col_Map")
lrow = .Cells(.Rows.Count, 1).End(xlUp).Row
colmap_arr() = Range(.Cells(2, 1), .Cells(lrow, 4))
End With
USED_WB.Close savechanges:=False
With ThisWorkbook.Sheets("Forecast")
lrow = .Cells(.Rows.Count, 1).End(xlUp).Row
lcol = .Cells(1, .Columns.Count).End(xlToLeft).Column
If lrow > 3 Then
ans = MsgBox("Do you want to replace LForecast with current forecast?", vbYesNo)
If ans = vbYes Then
ThisWorkbook.Sheets("L_Forecast").Cells.Clear
ThisWorkbook.Sheets("Forecast").Cells.Copy
With ThisWorkbook.Sheets("L_Forecast").Cells(1, 1)
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
End With
End If
End If
If lrow <= 4 Then lrow = 4
Range(.Cells(4, 1), .Cells(lrow, 1)).EntireRow.Delete
fhead_arr = Range(.Cells(2, 1), .Cells(2, lcol)).Value
End With
With ThisWorkbook.Sheets("L_Forecast")
lrow = .Cells(.Rows.Count, 1).End(xlUp).Row
lcol = .Cells(1, .Columns.Count).End(xlToLeft).Column
ldata_arr = Range(.Cells(2, 1), .Cells(lrow, lcol)).Value
End With
ReDim final_arr(UBound(data_arr), UBound(fhead_arr, 2))
For i = 1 To UBound(final_arr)
For j = 1 To UBound(final_arr, 2)
If Not IsEmpty(colmap_arr(j, 3)) Then
If IsNumeric(colmap_arr(j, 3)) Then
If IsNumeric(data_arr(i, colmap_arr(j, 3))) Then
final_arr(i, j) = CDbl(data_arr(i, colmap_arr(j, 3)))
Else
final_arr(i, j) = data_arr(i, colmap_arr(j, 3))
End If
ElseIf colmap_arr(j, 3) = "x" Then
For k = 1 To UBound(ldata_arr)
If ldata_arr(k, 4) = final_arr(i, 4) Then
final_arr(i, j) = ldata_arr(k, j)
End If
Next k
ElseIf colmap_arr(j, 3) = "f" Then
final_arr(i, j) = Replace(colmap_arr(j, 4), ";", ",")
End If
End If
Next j
Next i
With ThisWorkbook.Sheets("Forecast")
With .Cells(4, 1).Resize(UBound(final_arr), UBound(final_arr, 2))
.Value = final_arr
.Borders.LineStyle = xlContinuous
End With
End With
End Sub
End With
I have corrected the problem part of your code. Please note.
Sub import_new_forecast()
'Dim lrow, lcol, i, j, k As Long '~~> vba requires you to format each variable on the same line
Dim lrow As Long, lcol As Long, i As Long, j As Long, k As Long
Dim USED_WB As Workbook
Dim fcst_file As Variant
Dim data_arr(), ldata_arr(), colmap_arr(), fhead_arr(), head_arr()
Dim ans As Variant
Dim Target As Range
fcst_file = Application.GetOpenFilename(Filefilter:="XLS Files, *.xls", Title:="Provide RSM path", MultiSelect:=False)
Set USED_WB = Application.Workbooks.Open(fcst_file)
With USED_WB.ActiveSheet
lrow = .Cells(.Rows.Count, 1).End(xlUp).Row
' ~~> The line below doesn't make sense.
' Do Until CLng(.Cells(lrow, 2).Value) > 1 'Find last not empty row in RSM file
' lrow = lrow - 1
' Loop
lcol = .Cells(1, .Columns.Count).End(xlToLeft).Column
head_arr = .Range(.Cells(1, 1), .Cells(1, lcol)).Value '<~~ comma(.) added
data_arr = .Range(.Cells(2, 1), .Cells(lrow, lcol)).Value '<~~ comma(.) added
End With
With ThisWorkbook.Sheets("Col_Map")
lrow = .Cells(.Rows.Count, 1).End(xlUp).Row
colmap_arr() = .Range(.Cells(2, 1), .Cells(lrow, 4)) '<~~ comma(.) added .Range
End With
USED_WB.Close savechanges:=False
With ThisWorkbook.Sheets("Forecast")
lrow = .Cells(.Rows.Count, 1).End(xlUp).Row
lcol = .Cells(1, .Columns.Count).End(xlToLeft).Column
If lrow > 3 Then
ans = MsgBox("Do you want to replace LForecast with current forecast?", vbYesNo)
If ans = vbYes Then
ThisWorkbook.Sheets("L_Forecast").Cells.Clear
ThisWorkbook.Sheets("Forecast").Cells.Copy
With ThisWorkbook.Sheets("L_Forecast").Cells(1, 1)
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
End With
End If
End If
If lrow <= 4 Then lrow = 4
'Range(.Cells(4, 1), .Cells(lrow, 1)).EntireRow.Delete
.Range(.Cells(4, 1), .Cells(lrow, 1)).EntireRow.Clear '<~~ comma(.) added .Range
fhead_arr = .Range(.Cells(2, 1), .Cells(2, lcol)).Value '<~~ comma(.) added .Range
End With
With ThisWorkbook.Sheets("L_Forecast")
lrow = .Cells(.Rows.Count, 1).End(xlUp).Row
lcol = .Cells(1, .Columns.Count).End(xlToLeft).Column
ldata_arr = .Range(.Cells(2, 1), .Cells(lrow, lcol)).Value '<~~ comma(.) added .Range
End With
'ReDim final_arr( UBound(data_arr), UBound(fhead_arr, 2))
ReDim final_arr(1 To UBound(data_arr), 1 To UBound(fhead_arr, 2)) '<~~ dimesion index start at 1
'~~~> The way you define it is that the array starts at zero.
For i = 1 To UBound(final_arr)
For j = 1 To UBound(final_arr, 2)
If Not IsEmpty(colmap_arr(j, 3)) Then
If IsNumeric(colmap_arr(j, 3)) Then
If IsNumeric(data_arr(i, colmap_arr(j, 3))) Then
final_arr(i, j) = CDbl(data_arr(i, colmap_arr(j, 3)))
Else
final_arr(i, j) = data_arr(i, colmap_arr(j, 3))
End If
ElseIf colmap_arr(j, 3) = "x" Then
For k = 1 To UBound(ldata_arr)
If ldata_arr(k, 4) = final_arr(i, 4) Then
final_arr(i, j) = ldata_arr(k, j)
End If
Next k
ElseIf colmap_arr(j, 3) = "f" Then
final_arr(i, j) = Replace(colmap_arr(j, 4), ";", ",")
End If
End If
Next j
Next i
With ThisWorkbook.Sheets("Forecast")
With .Cells(4, 1).Resize(UBound(final_arr), UBound(final_arr, 2))
.Value = final_arr
.Borders.LineStyle = xlContinuous
End With
End With
End Sub
I have created a possapp for my bar. Everything works fine but i have to recalculate the listbox when delete 1 or more items.
This is my code for the delete button
Private Sub CommandButton84_Click()
Dim ItemTarget&, s, i%
s = 0
ItemTarget = ListBox1.ListCount
If ItemTarget > 0 Then
Me.ListBox1.RemoveItem ItemTarget - 1
For i = 0 To Me.ListBox1.ListCount - 1
s = s + Val(Me.ListBox1.List(i, 1))
Next
Me.TextBox1 = s
Else
MsgBox "De lijst is reeds leeg", vbInformation, "Café De Zoete Inval"
End If
Me.TextBox4 = Me.ListBox1.ListCount
End Sub
Private Sub CommandButton100_Click()
Dim LItem As Long
Dim IRange As Integer
Dim sht As Worksheet
Dim LastRow As Long
Dim rows As Integer
rows = 0
Set sht = ActiveSheet
For LItem = 0 To ListBox1.ListCount - 1
ListBox1.ColumnCount = 2
With Worksheets("Sheet6")
.Cells(LItem + 7, 1) = ListBox1.List(LItem, 0)
.Cells(LItem + 7, 2) = ListBox1.List(LItem, 1)
.Cells(LItem + 8, 1).EntireRow.Insert
rows = rows + 1
End With
With Sheets("Histo")
LastRow = .Cells.Find("*", searchorder:=xlByRows,
searchdirection:=xlPrevious).Row
If Time < "07:00:00" Then
.Cells(LastRow + 1, 1) = Format(Date - 1, "dd-mm-yyyy")
Else
.Cells(LastRow + 1, 1) = Date
End If
.Cells(LastRow + 1, 2) = ListBox1.List(LItem, 0)
.Cells(LastRow + 1, 3) = ListBox1.List(LItem, 1)
End With
Next LItem
With ThisWorkbook.Sheets("Sheet6")
ListBox1.Clear
TextBox2.Value = ""
TextBox1.Value = 0
Range("Sheet6!B5").ClearContents
For i = 1 To rows
.Cells(7, 1).EntireRow.Delete
Next
End With
ActiveWorkbook.Save
End Sub
Private Sub CommandButton1_Click()
With ThisWorkbook.Sheets("Sheet1")
Me.ListBox1.AddItem .Range("B2").Value
Me.ListBox1.Column(1, ListBox1.ListCount - 1) = Format(Val(.Range("C2").Value),
"€#,##0.00")
Me.TextBox1.Value = CDbl(Me.TextBox1.Value) + .Range("C2").Value
Me.TextBox1.Value = Format(Me.TextBox1.Value, "#,##0.00")
End With
Me.TextBox4 = Me.ListBox1.ListCount
End Sub
The script works perfectly.
Except if I don't press "Alt + Tab" 2-3 times it will take at least another 30 minutes to finish. But If I switch using "Alt + Tab" it finishes in less than 2 minutes.
My question is :
Is it due to improper use of loops ?
Is it Due to number of function calls I have used ?
Or the code itself is inefficient ?
Please let me know if I have missed any relevant info.
Private Sub CommandButton1_Click()
Call Interfac
Call DeleteRowBasedOnCriteria
Call DeleteRowBasedOnCriteria2
GenerateReport Worksheets("Report_Template"), Worksheets("Jira"), Worksheets("Script")
Call Deleterows
Call DefaultData
MsgBox "Report Generation Finished!"
End Sub
Public costcenterswitch As Long
Sub DeleteRowBasedOnCriteria()
Dim RowToTest As Long
Sheets("Jira").Select
For RowToTest = Cells(Rows.Count, 2).End(xlUp).Row To 2 Step -1
With Cells(RowToTest, 2)
If .Value = "CVEI-VR " _
Or .Value = "All Issues" _
Then _
Rows(RowToTest).EntireRow.Delete
End With
Next RowToTest
End Sub
Sub DeleteRowBasedOnCriteria2()
Dim RowToTest As Long
Sheets("Jira").Select
For RowToTest = Cells(Rows.Count, 1).End(xlUp).Row To 2 Step -1
With Cells(RowToTest, 1)
If .Value = "All Assignees" _
Then _
Rows(RowToTest).EntireRow.Delete
End With
Next RowToTest
End Sub
Sub DefaultData()
For Row = 2 To ActiveSheet.UsedRange.Rows.Count
Cells(Row, 1).Formula = 1
Cells(Row, 3).Formula = "SVDO"
Cells(Row, 4).Formula = costcenterswitch
Cells(Row, 5).Formula = "PS_99999"
Cells(Row, 9).Formula = 999
Cells(Row, 10).Formula = "EWH"
Cells(Row, 12).Formula = "H"
Cells(Row, 13).Formula = 0
Cells(Row, 14).Formula = 0
Cells(Row, 2).Formula = Row - 1
Next Row
End Sub
Sub Deleterows()
On Error Resume Next
Columns("K").SpecialCells(xlBlanks).EntireRow.Delete
End Sub
Sub Interfac()
Sheets("Script").Select
If IsEmpty(Range("O3").Value) = False Then
costcenterswitch = Range("O3").Value
Else
costcenterswitch = 900214
End If
End Sub
Sub GenerateReport(ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet)
Dim report As Workbook
Set report = Workbooks.Add
Dim ws1row As Long, ws2row As Long, ws1col As Integer, ws2col As Integer
Dim maxrow As Long, maxcol As Integer, colval1 As String, colval2 As String
Dim Row As Long, col As Integer, row3 As Integer, col3 As Integer, runsthirtyonetimes As Integer
With ws1.UsedRange
ws1row = .Rows.Count
ws1col = .Columns.Count
End With
With ws2.UsedRange
ws2row = .Rows.Count
ws2col = .Columns.Count
End With
maxrow = ws1row
maxcol = ws1col
If maxrow < ws2row Then maxrow = ws2row
If maxcol < ws2col Then maxcol = ws2col
Row = 1
For col = 1 To ws1col
Cells(Row, col).Formula = ws1.Cells(Row, col).Formula
Cells(Row, col).Font.Bold = True
Next col
counter = 2
For Row = 2 To ws2row
For runsthirtyonetimes = 1 To 31
Cells(counter, 7).Formula = ws2.Cells(Row, 2).Formula
Cells(counter, 8).NumberFormat = "yyyy-mm-dd"
Cells(counter, 8).Formula = ws2.Cells(Row, counter).Formula
Cells(counter, 11).Formula = ws2.Cells(Row, counter).Formula
If ws2.Cells(Row, 1).Formula = ws3.Cells(3, 16).Formula Then
Cells(counter, 6).Formula = ws3.Cells(3, 17).Formula
ElseIf ws2.Cells(Row, 1).Formula = ws3.Cells(4, 16).Formula Then
Cells(counter, 6).Formula = ws3.Cells(4, 17).Formula
ElseIf ws2.Cells(Row, 1).Formula = ws3.Cells(5, 16).Formula Then
Cells(counter, 6).Formula = ws3.Cells(5, 17).Formula
ElseIf ws2.Cells(Row, 1).Formula = ws3.Cells(6, 16).Formula Then
Cells(counter, 6).Formula = ws3.Cells(6, 17).Formula
ElseIf ws2.Cells(Row, 1).Formula = ws3.Cells(7, 16).Formula Then
Cells(counter, 6).Formula = ws3.Cells(7, 17).Formula
ElseIf ws2.Cells(Row, 1).Formula = ws3.Cells(8, 16).Formula Then
Cells(counter, 6).Formula = ws3.Cells(8, 17).Formula
ElseIf ws2.Cells(Row, 1).Formula = ws3.Cells(9, 16).Formula Then
Cells(counter, 6).Formula = ws3.Cells(9, 17).Formula
ElseIf ws2.Cells(Row, 1).Formula = ws3.Cells(10, 16).Formula Then
Cells(counter, 6).Formula = ws3.Cells(10, 17).Formula
ElseIf ws2.Cells(Row, 1).Formula = ws3.Cells(11, 16).Formula Then
Cells(counter, 6).Formula = ws3.Cells(11, 17).Formula
ElseIf ws2.Cells(Row, 1).Formula = ws3.Cells(12, 16).Formula Then
Cells(counter, 6).Formula = ws3.Cells(12, 17).Formula
ElseIf ws2.Cells(Row, 1).Formula = ws3.Cells(13, 16).Formula Then
Cells(counter, 6).Formula = ws3.Cells(13, 17).Formula
ElseIf ws2.Cells(Row, 1).Formula = ws3.Cells(14, 16).Formula Then
Cells(counter, 6).Formula = ws3.Cells(14, 17).Formula
ElseIf ws2.Cells(Row, 1).Formula = ws3.Cells(15, 16).Formula Then
Cells(counter, 6).Formula = ws3.Cells(15, 17).Formula
ElseIf ws2.Cells(Row, 1).Formula = ws3.Cells(16, 16).Formula Then
Cells(counter, 6).Formula = ws3.Cells(16, 17).Formula
ElseIf ws2.Cells(Row, 1).Formula = ws3.Cells(17, 16).Formula Then
Cells(counter, 6).Formula = ws3.Cells(17, 17).Formula
ElseIf ws2.Cells(Row, 1).Formula = ws3.Cells(18, 16).Formula Then
Cells(counter, 6).Formula = ws3.Cells(18, 17).Formula
Else
Cells(counter, 6).Formula = "BAD ID"
Cells(counter, col).Interior.Color = RGB(200, 0, 0)
Cells(counter, col).Font.Bold = True
End If
counter = counter + 1
Next runsthirtyonetimes
Next Row
counter = 2
For Row = 2 To ws2row
For runsthirtyonetimes = 4 To 34
Cells(counter, 8).Formula = ws2.Cells(1, runsthirtyonetimes).Formula
Cells(counter, 11).Formula = ws2.Cells(Row, runsthirtyonetimes).Formula
counter = counter + 1
Next runsthirtyonetimes
Next Row
Columns("A:Z").ColumnWidth = 20
Columns("G:G").ColumnWidth = 60
Rows("1:100").RowHeight = 15
End Sub
If you work across multiple sheets, clarifying the cell or range of sheets will reduce errors and improve speed. The code below illustrates what you are missing.
Sub DeleteRowBasedOnCriteria()
Dim RowToTest As Long
Dim Ws As Worksheet
Set Ws = Sheets("Jira")
With Ws
For RowToTest = .Cells(Rows.Count, 2).End(xlUp).Row To 2 Step -1
With .Cells(RowToTest, 2) '<~~ ws.Cells(RowToTest, 2)
If .Value = "CVEI-VR " _
Or .Value = "All Issues" _
Then _
Ws.Rows(RowToTest).EntireRow.Delete
End With
Next RowToTest
End Sub
I tried sumif function through excel vba but i'm getting '#value" error.
Sub xd()
R_lastrow = Sheets(1).Cells(Rows.Count, 1).End(xlUp).Row
R_lastcolumn = Sheets(1).Cells(1, Columns.Count).End(xlToLeft).Column
o_lastrow = Sheets(2).Cells(Rows.Count, 1).End(xlUp).Row
o_lastcolumn = Sheets(2).Cells(1, Columns.Count).End(xlToLeft).Column
For k = 2 To o_lastrow
For j = 2 To o_lastcolumn
Sheets("Sheet2").Cells(k, j).Value = Sheets("Sheet2").Evaluate("SUMIF(Sheet1!&range(cells(2,R_lastrow),cells(2,R_lastcolumn)),range(1,j),Sheet1!&range(cells(j,R_lastrow))")
Next j
Next k
End Sub
Could you please suggest me where i'm wrong
You need to substitute the range addresses into the formula.
Untested:
Sub xd()
Const f As String = "SUMIF(Sheet1!<r1>,<r2>,Sheet1!<r3>)"
R_lastrow = Sheets(1).Cells(Rows.Count, 1).End(xlUp).Row
R_lastcolumn = Sheets(1).Cells(1, Columns.Count).End(xlToLeft).Column
o_lastrow = Sheets(2).Cells(Rows.Count, 1).End(xlUp).Row
o_lastcolumn = Sheets(2).Cells(1, Columns.Count).End(xlToLeft).Column
f1 = Replace(f, "<r1>", Range(Cells(2, R_lastrow), _
Cells(2, R_lastcolumn)).Address(False, False))
For k = 2 To o_lastrow
For j = 2 To o_lastcolumn
frm = Replace(f1, "<r2>", Cells(1, j).Address(False, False))
frm = Replace(frm, "<r3>", Cells(j, R_lastrow).Address(False, False))
Debug.Print frm
Sheets("Sheet2").Cells(k, j).Value = Sheets("Sheet2").Evaluate(frm)
Next j
Next k
End Sub