I know a little bit about VBA but I can't seem to be able to work my way around this programming question.
I have a sheet where I want to program how many days it will take before the end of the tasking. Each Status are equal to a number of days, for exemple if a file is at the Pending stage it will take 180 total to be completed. But what i want is at each stage to write the number of days it will take. For example
Status is written in range E3:E160
If cell in range= Pending then
Offset 4 columns over and write 20, and offset 5 columns over and write 35 and offset 6 columns over and write 50, and offset 7 columns over and write 25, and offaet 8 columns over and write 15 and offset 9 columns over and write 15 and finally, offset 10 columns over and write 20
However if cell in range = "Planning" then offset 5 columns over and write 35, and offset 6 columns over and write 50 and so on until offset 10 columns over and write 20
The goal is tha for each status, the number of offset is based on the status.
Hope this help
I'm assuming ther will be a loop or something but I really can't figure it out.
Also it needs to be able to capture any new rows inserted within the range or outside the range.
Thanks to anyone who will be able to help me
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim LastRow As Long
Dim i As Long
LastRow = Range("E" & Rows.Count).End(xlUp).Row
For i = 3 To LastRow
If Range("E" & i).Value = "Pending" Then
Range("I" & i).Value = "20" And Range("J" & i).Value = 35 And Range("K" & i).Value = 50 And Range("L" & i).Value = 25 And Range("M" & i).Value = 15 And Range("N" & i).Value = 15 And Range("O" & i).Value = 20
ElseIf Range("E" & i).Value = "Planning" Then
Range("J" & i).Value = 35 And Range("K" & i).Value = 50 And Range("L" & i).Value = 25 And Range("M" & i).Value = 15 And Range("N" & i).Value = 15 And Range("O" & i).Value = 20
ElseIf Range("E" & i).Value = "Screening" Then
Range("K" & i).Value = 50 And Range("L" & i).Value = 25 And Range("M" & i).Value = 15 And Range("N" & i).Value = 15 And Range("O" & i).Value = 20
ElseIf Range("E" & i).Value = "Exam" Then
Range("L" & i).Value = 25 And Range("M" & i).Value = 15 And Range("N" & i).Value = 15 And Range("O" & i).Value = 20
ElseIf Range("E" & i).Value = "Interview" Then
Range("M" & i).Value = 15 And Range("N" & i).Value = 15 And Range("O" & i).Value = 20
ElseIf Range("E" & i).Value = "References" Then
Range("N" & i).Value = 15 And Range("O" & i).Value = 20
ElseIf Range("E" & i).Value = "Closing" Then
Range("O" & i).Value = 20
End If
Next i
End Sub
If Range("E" & i).Value = "Pending" Then
Range("I" & i).Value = 20
Range("J" & i).Value = 35
Range("K" & i).Value = 50
Range("L" & i).Value = 25
Range("M" & i).Value = 15
Range("N" & i).Value = 15
Range("O" & i).Value = 20
ElseIf Range("E" & i).Value = "Planning" Then
Range("J" & i).Value = 35
Range("K" & i).Value = 50
Range("L" & i).Value = 25
Range("M" & i).Value = 15
Range("N" & i).Value = 15
Range("O" & i).Value = 20`
You need to get rid of all the And statements in your Then clause. This is an example. You can change the rest. You might want to look into the Case Select method as well.
Related
I have this code and would like it to convert it to work for chrome instead of IE:
For Each htmlEle In ieObj.Document.getElementsByClassName("data data14902")(0).getElementsByTagName("tr")
With ActiveSheet
.Range("A" & i).Value = htmlEle.Children(0).textContent
.Range("B" & i).Value = htmlEle.Children(1).textContent
.Range("C" & i).Value = htmlEle.Children(2).textContent
.Range("D" & i).Value = htmlEle.Children(3).textContent
.Range("E" & i).Value = htmlEle.Children(4).textContent
.Range("F" & i).Value = htmlEle.Children(5).textContent
.Range("G" & i).Value = htmlEle.Children(6).textContent
.Range("H" & i).Value = htmlEle.Children(7).textContent
.Range("I" & i).Value = htmlEle.Children(8).textContent
.Range("J" & i).Value = htmlEle.Children(9).textContent
.Range("K" & i).Value = htmlEle.Children(10).textContent
.Range("L" & i).Value = htmlEle.Children(11).textContent
End With
i = i + 1
Next htmlEle
This is only a chunk of the code. What I'm doing is navigating to a particular webpage with a data table and what I want to do is copy all the data and paste it into excel.
Also, if there are parts of the code that can be improved, I'm open to it!
This is looping through a worksheet that is about 10k rows and it is taking a considerable amount of time. Is there a way to do this faster aside from an array? thank you
For i = 2 To spberowcnt
With spbe30
.Range("b" & i).Value = LCase(.Range("b" & i).Value)
.Range("d" & i).Value = LCase(.Range("d" & i).Value)
.Range("i" & i).Value = LCase(.Range("i" & i).Value)
.Range("j" & i).Value = LCase(.Range("j" & i).Value)
.Range("l" & i).Value = LCase(.Range("l" & i).Value)
.Range("m" & i).Value = LCase(.Range("m" & i).Value)
.Range("n" & i).Value = LCase(.Range("n" & i).Value)
.Range("p" & i).Value = LCase(.Range("p" & i).Value)
.Range("q" & i).Value = LCase(.Range("q" & i).Value)
.Range("r" & i).Value = LCase(.Range("r" & i).Value)
.Range("z" & i).Value = LCase(.Range("z" & i).Value)
.Range("aa" & i).Value = LCase(.Range("aa" & i).Value)
End With
Next i
For i = 2 To spberowcnt
With spbe60
.Range("b" & i).Value = LCase(.Range("b" & i).Value)
.Range("d" & i).Value = LCase(.Range("d" & i).Value)
.Range("i" & i).Value = LCase(.Range("i" & i).Value)
.Range("j" & i).Value = LCase(.Range("j" & i).Value)
.Range("l" & i).Value = LCase(.Range("l" & i).Value)
.Range("m" & i).Value = LCase(.Range("m" & i).Value)
.Range("n" & i).Value = LCase(.Range("n" & i).Value)
.Range("p" & i).Value = LCase(.Range("p" & i).Value)
.Range("q" & i).Value = LCase(.Range("q" & i).Value)
.Range("r" & i).Value = LCase(.Range("r" & i).Value)
.Range("z" & i).Value = LCase(.Range("z" & i).Value)
.Range("aa" & i).Value = LCase(.Range("aa" & i).Value)
End With
Next i
This is the array solution
Sub test()
Application.ScreenUpdating = False
Dim arrWorksheets(1) As Variant, ws As Worksheet
Set arrWorksheets(0) = spbe30
Set arrWorksheets(1) = spbe60
Dim arrColumns As Variant
arrColumns = Array("B", "D", "AA") 'adjust to your needs
Dim arrValues As Variant
Dim iWs As Long, iC As Long, i As Long
For iWs = 0 To UBound(arrWorksheets)
Set ws = arrWorksheets(iWs)
For iC = 0 To UBound(arrColumns)
arrValues = ws.Range(arrColumns(iC) & "2").Resize(spberowcnt).Value
For i = 1 To UBound(arrValues, 1)
arrValues(i, 1) = LCase(arrValues(i, 1))
Next
ws.Range(arrColumns(iC) & "2").Resize(spberowcnt).Value = arrValues
Next
Next
Application.ScreenUpdating = True
End Sub
Alternative: helper columns ...
You could try something like the following, looping over the columns instead of the individual cells and using Evaluate and Lower on the entire column. You could also process adjacent columns together.
cols = Array("B", "D", "I:J", "L:N", "P:R", "Z:AA")
For i = LBound(cols) to Ubound(cols)
Dim col As String
col = cols(i)
With spbe30
Dim rng As Range
Set rng = .Rows("2:" & spberowcnt).Columns(col)
rng.Value = .Evaluate("LOWER(" & rng.Address & ")")
End With
Next
But as mentioned in comments, an array is probably the way to go.
We have a large excel spreadsheet that has been in use for a view years now, the original coder for it has moved on. Today we started to get an a runtime error "Compile error, Syntax error" highlighting the below code
For n = 7 To lastpivotrow
If Range("AA" & n).Value <> "" And lastpivotrow < 50 Then
Range("B" & nextentry).Value = Range("AB" & n).Value
Range("C" & nextentry).Value = Range("AC" & n).Value
Range("D" & nextentry).Value = Range("AD" & n).Value
Range("E" & nextentry).Value = Range("AE" & n).Value
Range("B" & nextentry, "E" & nextentry).BorderAround LineStyle:=xlContinuous
Range("B" & nextentry, "E" & nextentry).Borders(xlInsideHorizontal).LineStyle = xlContinuous
Range("B" & nextentry, "E" & nextentry).Borders(xlInsideVertical).LineStyle = xlContinuous
Range("B" & nextentr+hen Range("B" & nextentry, "E" & nextentry).Interior.ColorIndex = 39
nextentry = nextentry + 1
Can anyone see whats wrong with this and provide feedback?
I have a matrix of dates with each one representing a different task, project, planned/actual start/finish. Please see the attached picture:
Screenshot of data
I have left everything in general terms as the actual names are confidential to my company. Anyhow, every row and column tells a different piece of information. Every two rows tells what project a date belongs to, and every row tell whether that date is a start or finish date. Every two columns tells what task the date belongs to, and every column states whether the date is a predicted date or an actual one.
Setting aside, what I am trying to do with this data is create a macro that will search all of these dates within a range set by the user, and list each date with the aforementioned information. So far, I have a code does this for individual rows:
Sub Sort_By_Date()
Dim StartDate As Date
Dim EndDate As Date
Dim i As Integer
StartDate = Range("F61").Value
EndDate = Range("G61").Value
'Clears out cells
Range("Z74:AD200").Value = ""
m = 74
For i = 71 To 200
If Range("C" & i).Value >= StartDate And Range("C" & i).Value <= EndDate Then
Range("Z" & m).Value = Range("C" & i).Value
Range("AA" & m).Value = Range("A" & i).Value
Range("AB" & m).Value = Range("C69")
Range("AC" & m).Value = Range("B" & i)
Range("AD" & m).Value = Range("C70")
m = m + 1
End If
If Range("D" & i).Value >= StartDate And Range("D" & i).Value <= EndDate Then
Range("Z" & m).Value = Range("D" & i).Value
Range("AA" & m).Value = Range("A" & i).Value
Range("AB" & m).Value = Range("D69")
Range("AC" & m).Value = Range("B" & i)
Range("AD" & m).Value = Range("D70")
m = m + 1
End If
If Range("E" & i).Value >= StartDate And Range("E" & i).Value <= EndDate Then
Range("Z" & m).Value = Range("E" & i).Value
Range("AA" & m).Value = Range("A" & i).Value
Range("AB" & m).Value = Range("E69")
Range("AC" & m).Value = Range("B" & i)
Range("AD" & m).Value = Range("E70")
m = m + 1
End If
...
...
...
Hopefully you can see the pattern here.
I can keep copying and pasting that If Then statement for every column, but there has to be a more efficient way to do it. I am fairly new to Excel macros (someone else actually wrote the basis of that code), so I am not sure how to make it do what I want it to. I imagine it will involve making the column letters into numbers, and then into variables, but I just don't know. I have tried looking it up, but I am having trouble applying what I found to my specific application.
So my main question: How do I get that If Then statement to repeat for every column of data I have without having to copy and paste it a million times?
Seems like you simply need a nested for loop:
Dim StartDate As Date
Dim EndDate As Date
Dim i As Integer, c as integer
StartDate = Range("F61").Value
EndDate = Range("G61").Value
'Clears out cells
Range("Z74:AD200").Value = ""
m = 74
'From column C to column AD
For c = 3 TO 30
For i = 71 To 200
If Range("C" & i).Value >= StartDate And Range("C" & i).Value <= EndDate Then
Range("Z" & m).Value = cells(i,c).Value
Range("AA" & m).Value = Range("A" & i).Value
Range("AB" & m).Value = cells(69,c).value
Range("AC" & m).Value = Range("B" & i)
Range("AD" & m).Value = cells(70,c).value
m = m + 1
End If
Next
Next
Turns out what I was looking for was this:
Sub Sort_By_Date()
Dim StartDate As Date
Dim EndDate As Date
Dim rwMin As Integer
Dim colMin As Integer
Dim rwMax As Integer
Dim colMax As Integer
Dim rwIndex As Integer
Dim colIndex As Integer
StartDate = Range("F61").Value
EndDate = Range("G61").Value
rwMin = 4
colMin = 3
rwMax = 37
colMax = 68
Range("L44:R2600").Value = ""
m = 44
For colIndex = colMin To colMax
For rwIndex = rwMin To rwMax
If Cells(rwIndex, colIndex).Value >= StartDate And Cells(rwIndex, colIndex).Value <= EndDate Then
Range("L" & m).Value = Cells(rwIndex, colIndex).Value
Range("M" & m).Value = Cells(rwIndex, 1).Value
Range("N" & m).Value = Cells(2, colIndex).Value
Range("O" & m).Value = Cells(1, colIndex).Value
Range("P" & m).Value = Cells(rwIndex, 2).Value
Range("Q" & m).Value = Cells(3, colIndex).Value
m = m + 1
End If
Next rwIndex
Next colIndex
End Sub
Basically, I needed to switch from using Range.Value to Cells.Value and then uses indexes. However, I seem to now have a separate issue of causing a runtime error with another function that I want to include, but that's a topic for a different post. It works right now without that function, though. Thanks for your input!
I am relatively new to vba macros and have learned to get around, but am not very good at debugging or troubleshooting problems.
I have this macro that is exiting on the line:
.Range("B" & y_lst).Resize(34, 10).Insert Shift:=xlDown
The macro works with 2 workbooks. 'wscflow' is a sheet on the inactive open workbook 'wbsource' that are declared globally. Fluid_Results is a routine in the active workbook, but another module. 'wsactive' is the sheet the macro accesses and is set in the routine that calls Read_Complex. 'Read_Pipe' is a routine in this module.
Can anyone tell me why this line would cause the macro to exit?
I should clarify; the line executes, but exits immediately afterward, it does not execute the next line.
Regards,
arthur
Sub Read_Complex()
Dim x_lst As Integer, y_lst As Integer, z_lst As Integer, i As Integer
wscflow.Range("T7").Value = 10
Application.Run ("'" & wbsource.Name & "'!Set_Rng")
x_lst = wscflow.Range("S7").Value
z_lst = wsactive.Range("B" & Rows.Count).End(xlUp).Row - 23
z_lst = ((z_lst - 24) + 330) / 34
If wscflow.Range("O" & x_lst).Value = "Total:" Then
x_lst = x_lst - 2
End If
Call Fluid_Results
If x_lst = 10 Then
MsgBox ("Only one pipe," & vbCr & _
"please use Single Pipe Flow")
Else
For x = 10 To x_lst
y_lst = wsactive.Range("B" & Rows.Count).End(xlUp).Row - 22
wscflow.Range("T7").Value = x
Application.Run ("'" & wbsource.Name & "'!Set_Rng")
Application.Run ("'" & wbsource.Name & "'!Rev_Copy")
Application.Run ("'" & wbsource.Name & "'!Fwd_Copy")
With wsactive
If x < 12 Then
y_lst = y_lst - 1
Call Read_Pipe
If .Name = "Series_Pipe_Flow" Then
.Range("F" & y_lst).Offset(8, 0).Formula = "=F14+F48"
For i = 17 To 20
.Range("F" & y_lst).Offset(i, 0).Formula = "=F" & i + 7 & "+F" & i + 41
Next i
For i = 22 To 23
.Range("F" & y_lst).Offset(i, 0).Formula = "=F" & i + 11 & "+F" & i + 45
Next i
ElseIf .Name = "Parallel_Pipe_Flow" Then
.Range("F" & y_lst).Offset(15, 0).Formula = "=F22+F56"
.Range("F" & y_lst).Offset(19, 0).Formula = "=F27+F61"
.Range("F" & y_lst).Offset(22, 0).Formula = "=F33+F67"
.Range("F" & y_lst).Offset(23, 0).Formula = "=F34+F68"
End If
Else
If x_lst = z_lst Then
y_lst = y_lst - 1
Else
.Range("B35:K68").Copy
.Range("B" & y_lst).Resize(34, 10).Insert Shift:=xlDown
' .Range("B" & y_lst).PasteSpecial xlPasteAll
y_lst = y_lst + 33
Application.CutCopyMode = False
End If
Call Read_Pipe
If .Name = "Series_Pipe_Flow" Then
.Range("F" & y_lst).Offset(8, 0).Value = .Range("F" & y_lst).Offset(8, 0).Value _
+ .Range("F" & y_lst).Offset(-20, 0).Value
.Range("F" & y_lst).Offset(11, 0).Value = .Range("F" & y_lst).Offset(-17, 0).Value
.Range("F" & y_lst).Offset(14, 0).Value = .Range("F" & y_lst).Offset(-14, 0).Value
For i = 17 To 20
.Range("F" & y_lst).Offset(i, 0).Value = .Range("F" & y_lst).Offset(i, 0).Value _
+ .Range("F" & y_lst).Offset(i - 27, 0).Value
Next i
For i = 22 To 23
.Range("F" & y_lst).Offset(i, 0).Value = .Range("F" & y_lst).Offset(i, 0).Value _
+ .Range("F" & y_lst).Offset(i - 23, 0).Value
Next i
ElseIf .Name = "Parallel_Pipe_Flow" Then
.Range("F" & y_lst).Offset(15, 0).Value = .Range("F" & y_lst).Offset(15, 0).Value _
+ .Range("F" & y_lst).Offset(-12, 0).Value
.Range("F" & y_lst).Offset(19, 0).Value = .Range("F" & y_lst).Offset(19, 0).Value _
+ .Range("F" & y_lst).Offset(-7, 0).Value
.Range("F" & y_lst).Offset(22, 0).Value = .Range("F" & y_lst).Offset(22, 0).Value _
+ .Range("F" & y_lst).Offset(-1, 0).Value
.Range("F" & y_lst).Offset(23, 0).Value = .Range("F" & y_lst).Offset(23, 0).Value _
+ .Range("F" & y_lst).Offset(0, 0).Value
End If
End If
End With
Next x
End If
z_lst = wsactive.Range("B" & Rows.Count).End(xlUp).Row - 23
z_lst = ((z_lst - 24) + 330) / 34
For i = 0 To z_lst - x_lst + 1
wsactive.Range("B" & y_lst + 1).Offset(-i * 34, 0).PageBreak = xlPageBreakManual
Next i
wscflow.Range("T7").ClearContents
End Sub
I think you may have a size difference between the copy and the insert. The resize function has 34 but the next one increase the variable by 33. I think the 34 needs to be 33.
If you print your variables to the debug window you'll e able to see what they are, e.g. debug.print "y_1st = " & y_1st.
Also for a visual add a .Range("B" & y_lst).Resize(34, 10).Select and break the code the next line after it to see if it has the correct size in excel.