Bloomberg data not populating before vba has finished running - excel

I know similar questions have been asked in the past, but looking through those posts, I haven't been able to find a solution to the following issue.
I have 2 subs that use Bloomberg API formulas. In the second (Setup_2) the variable LastRow1 is dependent on Setup_1 having populated to work properly.
Using checkStatus_1 and checkStatus_2 I can run each of the 2 setup subs independently, but when I try to create a separate sub calling them, it doesn't work, as the data that LastRow1 depends on isn't there.
Here is the relevant code:
Sub Setup_1()
Dim ws1 As Worksheet
Set ws1 = Worksheets("Returns")
ws1.Cells(2, 1).Formula = "=BDS(Control!B4,""INDX_MWEIGHT_HIST"",""END_DATE_OVERRIDE"",TEXT($A$1,""YYYYMMDD""))"
ws1.Cells(1, 4).Formula = "=BDH(A2&"" Equity"",""DAY_TO_DAY_TOT_RETURN_GROSS_DVDS"",$B$1,$A$1,""dir=h"")"
ws1.Cells(3, 4).Formula = "=BDH(A3&"" Equity"",""DAY_TO_DAY_TOT_RETURN_GROSS_DVDS"",$B$1,$A$1,""dir=h"",""dts=h"")"
checkStatus_1
End Sub
Sub Setup_2()
Dim ws1 As Worksheet
Set ws1 = Worksheets("Returns")
Dim LastRow1 As Long
LastRow1 = ws1.Cells(Rows.Count, 1).End(xlUp).Row
ws1.Cells(3, 4).Formula = "=BDH(A3&"" Equity"",""DAY_TO_DAY_TOT_RETURN_GROSS_DVDS"",$B$1,$A$1,""dir=h"",""dts=h"")"
ws1.Cells(3, 4).AutoFill Destination:=ws1.Range(ws1.Cells(3, 4), ws1.Cells(LastRow1, 4))
checkStatus_2
End Sub
Sub Setup_3()
Dim ws1 As Worksheet
Set ws1 = Worksheets("Returns")
Dim LastRow1 As Long
Dim LastCol1 As Long
Dim LCol As String
LastRow1 = ws1.Cells(Rows.Count, 1).End(xlUp).Row
LastCol1 = ws1.Cells(1, Columns.Count).End(xlToLeft).Column
LCol = Split(Cells(, LastCol1).Address, "$")(1)
ws1.Cells(2, 3).Formula = "=(STDEV.S(D2:" & LCol & "2)*SQRT(252))/100"
ws1.Cells(2, 3).AutoFill Destination:=ws1.Range(ws1.Cells(2, 3), ws1.Cells(LastRow1, 3))
End Sub
Sub checkStatus_1()
Dim ws1 As Worksheet
Dim rng As Range
Dim c As Range
Set ws1 = Worksheets("Returns")
Set rng = Application.Union(ws1.Cells(2, 1), ws1.Cells(1, 4), ws1.Cells(3, 4))
For Each c In rng
If "#N/A Requesting Data..." = c Or "#N/A Invalid Securiity" = c Then
Application.OnTime (Now + TimeValue("00:00:02")), "checkStatus_1"
Exit Sub
End If
Next c
End Sub
Sub checkStatus_2()
Dim ws1 As Worksheet
Dim rng As Range
Dim c As Range
Dim LastRow1 As Long
Set ws1 = Worksheets("Returns")
LastRow1 = ws1.Cells(Rows.Count, 1).End(xlUp).Row
Set rng = ws1.Range(ws1.Cells(3, 4), ws1.Cells(LastRow1, 4))
For Each c In rng
If "#N/A Requesting Data..." = c Then
Application.OnTime (Now + TimeValue("00:00:02")), "checkStatus_2"
Exit Sub
End If
Next c
End Sub

Related

Switch from Cells to Range

I see Range.AutoFill method (Excel) example:
Set sourceRange = Worksheets("Sheet1").Range("A1:A2")
Set fillRange = Worksheets("Sheet1").Range("A1:A20")
sourceRange.AutoFill Destination:=fillRange
I want to input a formula into the first empty column (always row 2) and then copy that down for all rows in the register (it's data copied from an outside source).
Sub SetNextEmptyFormula(strFormula As Variant)
Dim ws As Worksheet
Dim lCol As Long, lRow As Long
Set ws = Workbooks("myworkbook.xlsm").Worksheets("register")
' Always row 2 -> lRow, always in lCol
lCol = ws.Range("A1").End(xlToRight).Column
lRow = ws.Range("A1").End(xlDown).Row
ws.Cells(2, lCol + i).Value = CStr(strFormula)
Set sourceRange = ws.Range(???)
Set fillRange = ws.Range(???)
sourceRange.AutoFill Destination:=fillRange
End Sub
I'm not sure how you're going to build your formula, but if you're just looking for help referencing these cells, this will do:
Option Explicit
Sub UseSub()
Dim myFormula
myFormula = "=ROW()"
Call SetNextEmptyFormula(myFormula)
End Sub
Sub SetNextEmptyFormula(strFormula As Variant)
Dim WS As Worksheet
Dim lCol As Long, lRow As Long
Dim fillRange As Range
Set WS = Workbooks("myworkbook.xlsm").Worksheets("register")
'Set WS = Workbooks("Book1.xlsm").Worksheets("register")
With WS
' Always row 2 -> lRow, always in lCol
lCol = .Range("A1").End(xlToRight).Column
lRow = .Range("A1").End(xlDown).Row
.Cells(2, lCol + 1).Formula = CStr(strFormula)
'FillDown Only requires you reference the whole range Once, You only need "FillRange"
'Set sourceRange = ws.Range(???)
Set fillRange = .Range(.Cells(2, lCol + 1), .Cells(lRow, lCol + 1))
fillRange.FillDown
End With
End Sub

Copy specific cells based on value in the same row in sheet1(table1) and paste into sheet2(table2) next available row

This code works, but it puts the values at the bottom of Sheet2(Table2), instead of next available row in table2. Any suggestions would be appreciated. Thanks
https://drive.google.com/file/d/19fZ6GLGtVNd13I-GTgLVjnfKlzrwx05U/view?usp=sharing
Sub Macro()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet2")
Dim LastRow As Long
Dim s As Long
Dim myRow As Long
s = ws.Range("A" & Application.Rows.Count).End(xlUp).Row
LastRow = Sheets("Sheet1").Cells(Rows.Count, "I").End(xlUp).Row
For myRow = 2 To LastRow
If Sheets("Sheet1").Cells(myRow, "I") = "INACTIVE" Then
ws.Range("A" & s + 1) = Sheets("Sheet1").Cells(myRow, "A")
ws.Range("B" & s + 1) = Sheets("Sheet1").Cells(myRow, "B")
ws.Range("C" & s + 1) = Sheets("Sheet1").Cells(myRow, "C")
ws.Range("D" & s + 1) = Sheets("Sheet1").Cells(myRow, "I")
End If
Next myRow
End Sub
Copying Data From One Excel Table to Another
Dealing with Excel tables in VBA can be quite tricky. This is a simple user-friendly version. You could dive much deeper into it by using (an array of) the table headers in the loop and whatnot.
Option Explicit
Sub Macro()
Dim sws As Worksheet: Set sws = ThisWorkbook.Worksheets("Sheet1")
Dim stbl As ListObject: Set stbl = sws.ListObjects("Table1")
Dim dws As Worksheet: Set dws = ThisWorkbook.Worksheets("Sheet2")
Dim dtbl As ListObject: Set dtbl = dws.ListObjects("Table2")
Dim sCell As Range
Dim srrg As Range
Dim drrg As Range
Dim r As Long
For Each sCell In stbl.ListColumns("Status").DataBodyRange
r = r + 1
If StrComp(CStr(sCell.Value), "INACTIVE", vbTextCompare) = 0 Then
Set srrg = stbl.ListRows(r).Range
Set drrg = dtbl.ListRows.Add.Range
drrg.Cells(1).Value = srrg.Cells(1).Value
drrg.Cells(2).Value = srrg.Cells(2).Value
drrg.Cells(3).Value = srrg.Cells(3).Value
drrg.Cells(4).Value = srrg.Cells(9).Value
End If
Next sCell
End Sub
the below code should work as s variable is inside the loop.
P.S.
Updated the code to match your example.
Also, the sheet2 has table, so the last row was not detected correctly by End(xlUp).Row
The problem was also with myRow =2
Sub Macro()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet2")
Dim ws1 As Worksheet: Set ws1 = ThisWorkbook.Sheets("Sheet1")
Dim LastRow As Long
Dim s As Long
Dim myRow As Long
LastRow = ThisWorkbook.Sheets("Sheet1").Cells(Rows.Count, "I").End(xlUp).Row
For myRow = 1 To LastRow
s = ws.Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row + 1
If ws1.Cells(myRow, "I") = "INACTIVE" Then
ws.Range("A" & s & ":C" & s) = ws1.Range("A" & myRow & ":C" & myRow).Value
ws.Range("D" & s) = "INACTIVE"
End If
Next myRow
MsgBox "OK"
End Sub

Macro/VBA: How to copy "striked-out" rows to another worksheet

I have a table with certain rows with "striked-out" font. The objective is to cut these rows and paste them into another sheet.
So far, I have the following code, and is not working (EDIT: a new sheet gets created but nothing is cut nor pasted):
Sub test()
Dim i As Long, lrow As Long
lrow = Cells(Rows.Count, "A").End(xlUp).Row
Sheets.Add After:=ActiveSheet
For i = 2 To lrow
If Cells(i, 1).Font.Strikethrough = True Then
Cells(i, 1).EntireRow.Cut
Sheets(ActiveSheet.Index + 1).Paste
End If
Next i
End Sub
How would I fix this?
More like this:
Sub test()
Dim i As Long, lrow As Long, wsSrc As Worksheet, wsDest As Worksheet
Dim destRow As Long
Set wsSrc = ActiveSheet 'or something more specific
lrow = wsSrc.Cells(wsSrc.Rows.Count, "A").End(xlUp).Row
'get a reference to the sheet when adding it
Set wsDest = wsSrc.Parent.Sheets.Add(After:=ActiveSheet)
destRow = wsDest.Cells(wsDest.Rows.Count, "A").End(xlUp).Row + 1
For i = 2 To lrow
If wsSrc.Cells(i, 1).Font.Strikethrough = True Then
wsSrc.Rows(i).Cut wsDest.Cells(destRow, 1)
destRow = destRow + 1 'next paste row
End If
Next i
End Sub

Copy to the next available line with my code

With the code I am currently using it will paste the information from Worksheet 1 to worksheet 2 in the Top line of worksheet2. What I want next is to use the same code but for different cell values and to copy the information from worksheet 1 to worksheet 2 but in the next available line in worksheet 2.
I have been researching about excel macros and vba for a while now and I am still having trouble. I have worked on not using select and activate within my excel code but I am still having trouble with my code now. I am trying to automate my excel workbook as much as I can for easier use.
Sub Copy()
Dim Cell As Range
Dim myRow As Long
myRow = 1
With Sheets("Sheet1")
For Each Cell In .Range("A1:A" & .Cells(.Rows.Count, "A").End(xlUp).Row)
If Cell.Value = "Tuck Chow" And Cell.Offset(0, 1).Value = "OPT" Then
.Rows(Cell.Row).Copy Destination:=Sheets("Sheet2").Rows(myRow)
myRow = myRow + 1
End If
Next Cell
End With
End Sub
I would do something like this:
Sub Copy()
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim newRow As Long
'setting sheets
Set sh1 = ThisWorkbook.Worksheets("Sheet1")
Set sh2 = ThisWorkbook.Worksheets("Sheet2")
With sh1
For Each cel In .Range(.Cells(1, 1), .Cells(Rows.Count, 1).End(xlUp))
If cel.Value = "Tuck Chow" And cel.Offset(0, 1).Value = "OPT" Then
'getting new row on Sheet2
If sh2.Cells(1, 1) = "" Then
newRow = 1
Else
newRow = sh2.Cells(Rows.Count, 1).End(xlUp).Row + 1
End If
'copying
cel.EntireRow.Copy Destination:=sh2.Cells(newRow, 1)
End If
Next cel
End With
'deselecting row
sh2.Cells(1, 1).Select
End Sub
Try:
Option Explicit
Sub test()
Dim LastRow1 As Long, LastRow2 As Long, i As Long
With ThisWorkbook.Worksheets("Sheet1")
LastRow1 = .Cells(.Rows.Count, "A").End(xlUp).Row
For i = 1 To LastRow1
If .Range("A" & i).Value = "Tuck Chow" And .Range("B" & i).Value = "OPT" Then
LastRow2 = ThisWorkbook.Worksheets("Sheet2").Cells(ThisWorkbook.Worksheets("Sheet2").Rows.Count, "A").End(xlUp).Row
.Rows(i).Copy ThisWorkbook.Worksheets("Sheet2").Rows(LastRow2 + 1)
End If
Next i
End With
End Sub

VBA- Transferring data to another work sheet if a column has certain text and pasting it in a certain cell range

I am currently trying to filter data and paste it into another sheet to a certain range but it is only posting the latest data row. How do I fix the code so that it selects all the rows with the code word and pastes it into the other sheet.
This is my code:
Private Sub CommandButton1_Click()
Dim lastrow As Long, i As Long
lastrow = Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
If Sheets("sheet1").Cells(i, 1) = "pp" Then
Sheets("sheet1").Range(Cells(i, 2), Cells(i, 5)).Copy
ActiveSheet.Paste Destination:=Worksheets("Sheet5").Range("A11:A22")
End If
Next
End Sub
I think this is what you want.
Private Sub CommandButton1_Click()
Dim ws1 as Worksheet: Set ws1 = Thisworkbook.Sheets("Sheet1")
Dim ws2 as Worksheet: Set ws2 = Thisworkbook.Sheets("Sheet5")
Dim LRow1 As Long, LRow2 as Long, i As Long
LRow1 = ws1.Range("A" & ws1.Rows.Count).End(xlUp).Row
LRow2 = ws2.Range("A" & ws2.Rows.Count).End(xlUp).Row
For i = 2 To lastrow
If ws1.Cells(i, 1) = "pp" Then
ws1.Range(Cells(i, 1), Cells(i, 5)).Copy
ws2.Range("A" & LRow + 1).PasteSpecial xlPasteValues
End If
Next
End Sub
Here is a more effecient method using a For Each loop and one instance of Copy/Paste instead of 1 iteration for every matched cell.
Option Explicit
Sub Copy()
Dim ws1 As Worksheet: Set ws1 = ThisWorkbook.Sheets("Sheet1")
Dim ws2 As Worksheet: Set ws2 = ThisWorkbook.Sheets("Sheet2")
Dim TargetRange As Range, TargetCell As Range, CopyRange As Range
Set TargetRange = ws1.Range("A2:A" & ws.Range("A" & ws.Rows.Count).End(xlUp).Row)
For Each TargetCell In TargetRange
If TargetCell = "pp" Then
If CopyRange Is Nothing Then
Set CopyRange = TargetCell.Resize(1, 4)
Else
Set CopyRange = Union(CopyRange, TargetCell.Resize(1, 4))
End If
End If
Next TargetCell
CopyRange.Copy
ws2.Range("A" & ws2.Range("A" & ws2.Rows.Count).End(xlUp).Row).PasteSpecial xlPasteValuesAndNumberFormats
End Sub
Another method would be to apply a filter for your target value pp and then copy/paste visible cells.

Resources