Excel VBA, Loop Recording Answer - vba

I am trying to write some code to choose start time and end times of a shift using input data for shift duration which is read from a column (reports times if cell is not empty).
I am just debugging at the moment before I try and hard code with variables and ranges however
my
If Cells(i, j).Value <> "" Then
Shiftduration = Cells(i, j).Value * (0.5 / 12)
lines are not working correctly and are returning 0 values when I am testing, as their values are not being recorded. Thus it not taking into account the actual start time of a shift ie (Shift end time - shift duration)
Sub Test2()
Sheets("Test").Select
Dim i As Long, j As Long
Dim Shiftduration As Long
Dim ShiftStart As Long
For i = 31 To 44
For j = 4 To 4
If Cells(i, j).Value <> "" Then
Shiftduration = Cells(i, j).Value * (0.5 / 12)
nextshift = Cells(i + 1, 1).Value
ShiftstartRange = nextshift - Shiftduration
Cells(1, 21) = nextshift
Cells(1, 22) = Shiftduration
Cells(i, 8) = ShiftstartRange
Else
End If
Next j
Next i
End Sub
All of my code
Thanks!

I changed Shiftduration and ShiftStart from Long to Double.
And I specify with which sheet your are working.
Let me know if its works like you want
Sub Test2()
Dim wb As Workbook
Dim ws As Worksheet
Dim i As Long, j As Long
Dim Shiftduration As Double
Dim ShiftStart As Double
Set wb = ThisWorkbook
Set ws = wb.Sheets("Test")
For i = 31 To 44
For j = 4 To 4
If ws.Cells(i, j).Value <> "" Then
Shiftduration = ws.Cells(i, j).Value * (0.5 / 12)
nextshift = ws.Cells(i + 1, 1).Value
ShiftstartRange = nextshift - Shiftduration
ws.Cells(1, 21) = nextshift
ws.Cells(1, 22) = Shiftduration
ws.Cells(i, 8) = ShiftstartRange
Else
End If
Next j
Next i
End Sub

Related

VBA EXCEL Compare Columns and bring over the value

Image1
Hi, Referring to the image, I am trying to compare column G and Column K, if the value is the same then copy the value in column J to column F. However, my code doesn't copy the value from Column J to F.
Sub createarray1()
Dim i As Integer
Dim j As Integer
Dim masterarray As Range
Set masterarray = Range("D3:G12")
Dim sourcearray As Range
Set sourcearray = Range("H3:K26")
For i = 1 To 10
For j = 1 To 25
If masterarray(i, 4).Value = sourcearray(j, 4).Value Then
masterarray(i, 3) = sourcearray(j, 3).Value
Else
masterarray(i, 3).Value = ""
End If
Next
Next
End Sub
Function concatenate()
Dim nlastrow As Long
For i = 2 To Cells(Rows.Count, "D").End(xlUp).Row
Cells(i, "G").Value = Cells(i, "D").Value & "_" & Cells(i, "E").Value
Next i
Dim nnlastrow As Long
For i = 2 To Cells(Rows.Count, "H").End(xlUp).Row
Cells(i, "K").Value = Cells(i, "H").Value & "_" & Cells(i, "I").Value
Next i
End Function
Use variant arrays, that way you limit the number of calls to the sheet to only 3.
When your positive is found you need to exit the inner loop.
Sub createarray1()
Dim i As Long
Dim j As Long
Dim masterarray As Variant
Dim sourcearray As Variant
With ThisWorkbook.Worksheets("Sheet1") ' change to your sheet
masterarray = .Range("D3:G12")
sourcearray = .Range("H3:K26")
For i = LBound(masterarray, 1) To UBound(masterarray, 1)
masterarray(i, 3) = ""
For j = LBound(sourcearray, 1) To UBound(sourcearray, 1)
If masterarray(i, 4) = sourcearray(j, 4) Then
masterarray(i, 3) = sourcearray(j, 3)
Exit For
End If
Next j
Next i
.Range("D3:G12") = masterarray
End With
End Sub
But this can all be done with the following formula:
=INDEX(J:J,MATCH(G3,K:K,0))
Put it in F3 and copy/drag down.

excel vba finding with like or regex

I'm writing a VBA program.
I have a problem with finding this string [BLOCKED] in one column
For j = 0 To 4
For i = 2 To lastrow
If Cells(i, 12).Value = groupnames(j) And Cells(i, 8).Value Like "*" & "[BLOCKED]" & "*" Then
groupsum(j) = groupsum(j) + 1
End If
Next i
Next j
The problem is I have 96 cells for this string but the program found 500 how can I do this to going work?
Thanks for help
The syntax of your Like operation is incorrect. Use:
... Like "*[[]BLOCKED]*"
[...] is a Character class. So, the way you have it written in your question, it will find any single character in the set of BLOCKED. That is not what you want, apparently.
To match the [ character, you enclose it within a character class, as I have shown. To match the ] character, it must be outside of a character class.
here is my code
Sub blocked()
Dim SfileUsers As String
Dim path As String
Dim pathread As String
Dim sFileread As String
Dim lastrow As Long
Dim keres() As Variant
Dim groupadd() As String
Dim groupnames(4) As String
Dim groupsum(4) As Long
path = "C:\Users\uids9282\Desktop\"
SfileUsers = "Users.xlsx"
Workbooks.Open path & SfileUsers
Dim hossz As Long
hossz = Sheets(1).Cells(Rows.Count, 1).End(xlUp).Row
ReDim keres(hossz)
ReDim groupadd(hossz)
For i = 2 To hossz
keres(i) = Sheets(1).Cells(i, 2).Value
groupadd(i) = Sheets(1).Cells(i, 4).Value
Next i
'fájlmegnyitás
pathread = "C:\Users\uids9282\Desktop\20170703\"
sFileread = "open.xml"
If Dir(pathread & sFileread) = sFileread Then
Workbooks.Open pathread & sFileread
lastrow = Workbooks(sFileread).Sheets(1).Cells(Rows.Count, 1).End(xlUp).Row
Else
MsgBox ("Nincs ilyen nevű excel táblázat. Kérem próbálkozzon újra")
End If
'groupok hozzáadása a fájlhoz
Dim user As String
For j = 2 To hossz
For i = 2 To lastrow
user = Trim(Cells(i, 5).Value)
If user = keres(j) Then
Cells(i, 12).Value = groupadd(j)
End If
Next i
Next j
'group szummázása és átírása
ThisWorkbook.Activate
For i = 2 To 6
groupnames(i - 2) = Cells(i, 1).Value
Next i
Workbooks(sFileread).Activate
For j = 0 To 4
For i = 2 To lastrow
If Cells(i, 12).Value = groupnames(j) And Cells(i, 8).Value Like "*[[]BLOCKED[]]*" Then 'itt van benne a hiba!! groupsum(j) = groupsum(j) + 1
End If
Next i
Next j
ThisWorkbook.Activate
For j = 2 To 6
Cells(j, 4).Value = groupsum(j - 2)
Next j
Workbooks(SfileUsers).Close SaveChanges:=False
Workbooks(sFileread).Close SaveChanges:=True
End Sub
this is my excel file where i want to searching

VBA If exists copy to the next row in antoher sheet

I'm trying to sort in another sheet values that I have received and I wrote:
Sub copy_to_report()
Dim i As Integer
Dim Lastrow As Long
For i = 2 To 500
If Sheets("Sheet1").Cells(i, 24) <> "" & Sheets("Sheet1").Cells(i, 25) <> "" Then
Lastrow = Sheets("report").Cells(Rows.Count, 1).End(xlUp).Row
Sheets("report").Cells(Lastrow, 3) = Cells(i, 24)
Sheets("report").Cells(Lastrow, 4) = Cells(i, 25)
End If
Next
End Sub
However it doesn't work. I'd like to check if in a row there is something in 25 and 24 and if yes, copy it from sheet1 to my "report"sheet. Could you please help me? :)
Some of your Cells are not qualified with the relevant Worksheet, the same goes for Lastrow.
You may try something like the code below:
Option Explicit
Sub copy_to_report()
Dim i As Long
Dim Lastrow As Long
Dim ShtReport As Worksheet
Set ShtReport = Worksheets("report")
With Worksheets("Sheet1")
For i = 2 To 500
If .Cells(i, 24) <> "" And .Cells(i, 25) <> "" Then
'Lastrow = ShtReport.Cells(ShtReport.Rows.Count, 1).End(xlUp).Row
' maybe it's better to check for last row in Column "C"
Lastrow = ShtReport.Cells(ShtReport.Rows.Count, "C").End(xlUp).Row
ShtReport.Cells(Lastrow, 3) = .Cells(i, 24)
ShtReport.Cells(Lastrow, 4) = .Cells(i, 25)
End If
Next
End With
End Sub

My vba loop pulls back all the correct data when I step through but when I run the Macro it does not

I have tried to build a loop that pulls back certain data when it meets a criteria, then posts the results in my 'Main' sheet.
Unfortunately, when you run the macro it does not pull back all of the data.
However, and this in my opinion is super weird, when you step through it does.
There are no error messages at any point in the code and the code runs the whole way through if you step through/just run the macro.
I have posted my code below:
Sub Loop_Data()
'BR stands for Blank Row
Dim i As Integer, j As Integer, k As Integer, m As Integer, BRMAin As Integer, BRData As Integer, BRPhysNot As Integer, _
SearchRange As Range, strID As String, ExtEnd As Integer, FindRow As Range
BRMAin = Sheets("Main").Cells(Rows.Count, "W").End(xlUp).Row
BRData = Sheets("Data").Cells(Rows.Count, "A").End(xlUp).Row
BRPhysNot = Sheets("PhysNot").Cells(Rows.Count, "A").End(xlUp).Row
Set SearchRange = Sheets("Data").Range("A3:A" & BRData)
Sheets("CoData").Activate
'assign j for number of rows (units) and i to start at 6 (column J) and end at 21
For j = 2 To 48
i = 35
Do Until i = 52
'criteria
If Cells(j, i - 1).Interior.Color <> RGB(51, 51, 51) And Cells(j, i - 1) > 0 And Cells(j, i).Interior.Color = RGB(51, 51, 51) Then
'find duration o
m = 0
Do While Cells(j, i + m).Interior.Color = RGB(51, 51, 51)
m = m + 1
Loop
'check that the flagged is definitely matching criteria
If Cells(j, i + m) = 0 Then
'set string ID as the string of uni & period to find in the helper column of Data sheet
'set k as row which that occurs in
strID = Cells(1, i) & Cells(j, 3)
Set FindRow = SearchRange.Find(strID)
k = FindRow.Row
'Pull back data into main sheet
ThisWorkbook.Sheets("Main").Range("X" & BRMAin + 1) = Sheets("Data").Cells(k, 8)
ThisWorkbook.Sheets("Main").Range("V" & BRMAin + 1) = Sheets("Data").Cells(k, 4)
ThisWorkbook.Sheets("Main").Range("W" & BRMAin + 1) = Sheets("Data").Cells(k, 2)
ThisWorkbook.Sheets("Main").Range("Y" & BRMAin + 1) = m
ThisWorkbook.Sheets("Main").Range("Z" & BRMAin + 1) = Sheets("CoData").Cells(1, i)
End If
End If
i = i + 1
Loop
Next j
End Sub
If a Wait or DoEvents doesn't work, instead of using
Set FindRow = SearchRange.Find(strID)
k = FindRow.Row
You could go with
k = 0
For Each SearchCell In SearchRange
If SearchCell.Text = strID Then k = SearchCell.Row
Next
I'm not 100% sure, but I suspect it has to do with you having multiple sheets, but you aren't being specific about which sheet your ranges are calling to.
I'd add in call out to worksheets for each range and cell. See my code below and let me know if it helps.
Sub Loop_Data() 'loops through CoData Sheet
'BR stands for Blank Row
Dim wb As Workbook, wsData As Worksheet, wsMain As Worksheet, wsPhys As Worksheet, wsCoData As Worksheet
Dim i As Integer, j As Integer, k As Integer, m As Integer, BRMAin As Integer, BRData As Integer, BRPhysNot As Integer
Dim SearchRange As Range, strID As String, ExtEnd As Integer, FindRow As Range
Set wb = ThisWorkbook
Set wsData = wb.Sheets("Data")
Set wsMain = wb.Sheets("Main")
Set wsPhys = wb.Sheets("PhysNot")
Set wsCoData = wb.Sheets("CoData")
BRMAin = wsMain.Cells(Rows.Count, "W").End(xlUp).Row
BRData = wsData.Cells(Rows.Count, "A").End(xlUp).Row
BRPhysNot = wsPhys.Cells(Rows.Count, "A").End(xlUp).Row
Set SearchRange = wsData.Range("A3:A" & BRData)
wsCoData.Activate 'Not necessary to activate a sheet if you need to pull data from it if you link a range to a specific sheet.
'assign j for number of rows (units) and i to start at 6 (column J) and end at 21
For j = 2 To 48
i = 35
Do Until i = 52
'criteria
If wsCoData.Cells(j, i - 1).Interior.Color <> RGB(51, 51, 51) And wsCoData.Cells(j, i - 1) > 0 And wsCoData.Cells(j, i).Interior.Color = RGB(51, 51, 51) Then
'find duration o
m = 0
Do While wsCoData.Cells(j, i + m).Interior.Color = RGB(51, 51, 51)
m = m + 1
Loop
'check that the flagged is definitely matching criteria
If wsCoData.Cells(j, i + m) = 0 Then
'set string ID as the string of uni & period to find in the helper column of Data sheet
'set k as row which that occurs in
strID = wsCoData.Cells(1, i) & wsCoData.Cells(j, 3)
Set FindRow = SearchRange.Find(strID)
k = FindRow.Row
'Pull back data into main sheet
wsMain.Range("X" & BRMAin + 1) = wsData.Cells(k, 8)
wsMain.Range("V" & BRMAin + 1) = wsData.Cells(k, 4)
wsMain.Range("W" & BRMAin + 1) = wsData.Cells(k, 2)
wsMain.Range("Y" & BRMAin + 1) = m
wsMain.Range("Z" & BRMAin + 1) = wsCoData.Cells(1, i)
End If
End If
i = i + 1
Loop
Next j
End Sub
I had to guess on the unlabeled ranges, I just assumed they had to do with the CoData Worksheet since that is what you had active last.
Also, if it helps at all, I noticed you keep calling out to a specific color, you can make that a variable too so you don't have keep typing it so much. See below.
Dim grey as Long
grey = RGB(51, 51, 51)
'Colors are just stored as Longs, in some cases Integer will work, but its mostly safer to just always stick to Long.
'So your grey would equal 3355443: 51 + 51*256 + 51 *256*256
'Example Uses...
If wsCoData.Cells(j, i - 1).Interior.Color <> grey And wsCoData.Cells(j, i - 1) > 0 And wsCoData.Cells(j, i).Interior.Color = grey Then
'...Your code
End if
Do While Cells(j, i + m).Interior.Color = grey
m = m + 1
Loop

Use VBA open a Excel file, and run a loop, but the loop will be always skipped

I want to run loop on the same workbook, but it also give me nothing. But If I run this VBA directly on the workbook (CGDSOUSD), it works well. So I am wondering how to run VBA after let VBA open a new file.
Dim rownumber As Integer
Dim colnumber As Integer
Dim total As Double
colnumber = 1
For colnumber = 1 To 23
If Cells(8, colnumber) = "DELTA" Then
total = 0
rownumber = 9
Do Until Cells(rownumber, colnumber) = "" And Cells(rownumber + 1, colnumber) = "" And Cells(rownumber + 5, 1) = ""
If Cells(rownumber, 1) = "" And (Cells(rownumber, 7).Value = "DSO TROPS" Or Cells(rownumber, 8).Value = "DSO TROPS" Or Cells(rownumber, 6).Value = "DSO TROPS") Then
total = total + (Cells(rownumber, colnumber).Value)
Else
End If
rownumber = rownumber + 1
Loop
Else
End If
colnumber = colnumber + 1
Next colnumber
total = Round(total, 2) 'will be imputed into E20 in risk tools
MsgBox total
Maybe Do Until is False.
To iterate through cells I always determine the lastrow and use a for loop.
See basic example below.
ps: use ActiveCell and activate one.
'place a value in cell A1 to A4 for test.
Sub test()
Dim lastrow As Long
lastrow = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
For i = 1 To lastrow
If Cells(i, 1) <> "" Then
Cells(i, 2).Value = "not empty"
End If
Next i
End Sub