I am new to VBA and am trying to learn some of the functionality. What I have created is a code in excel that connects to an API and pulls data into a table. I need it to loop for a specified period of time (9am to 4pm) and refresh every 30 seconds. My problem is I just don't know how to accomplish this. Here is my code Please help! Thanks!!
Also the table being populated is setup in the following Columns: "Symbol" "Name" "Ask" "Bid" "Price" "Days Range" "1yr Target Price" "Volume" "Avg Daily Vol"
My Code:
Private Sub BTN_Start_Click()
Dim W As Worksheet: Set W = ActiveSheet
Dim Last As Integer: Last = W.Range("A10000").End(xlUp).Row
If Last = 1 Then Exit Sub
Dim Symbol As String
Dim i As Integer
For i = 2 To Last
Symbol = Symbol & W.Range("A" & i).Value & "+"
Next i
Symbol = Left(Symbol, Len(Symbol) - 1)
Dim url As String: url = "http://finance.yahoo.com/d/quotes.cvs?s=" & Symbol & "&f=snb2b3k1m2t8va2"
Dim Http As New winhttprequest
Http.Open "GET", url, False
Http.send
Dim Resp As String: Resp = Http.ResponseText
Dim Lines As Variant: Lines = Split(Resp, vbNewLine)
Dim sLine As String
Dim Values As Variant
For i = 0 To UBound(Lines)
sLine = Lines(i)
If InStr(sLine, ",") > 0 Then
Values = Split(sLine, ",")
W.Cells(i + 2, 2).Value = Split(Split(sLine, Chr(34) & "," & Chr(34))(1), Chr(34))(0)
W.Cells(i + 2, 3).Value = Values(UBound(Values) - 6)
W.Cells(i + 2, 4).Value = Values(UBound(Values) - 5)
W.Cells(i + 2, 5).Value = Values(UBound(Values) - 4)
W.Cells(i + 2, 6).Value = Values(UBound(Values) - 3)
W.Cells(i + 2, 7).Value = Values(UBound(Values) - 2)
W.Cells(i + 2, 8).Value = Values(UBound(Values) - 1)
W.Cells(i + 2, 9).Value = Values(UBound(Values))
End If
Next i
W.Cells.Columns.AutoFit
End Sub
You could put the main part of your code in this loop. It won't exit until the time is up.
Do while timevalue(now()) > #9:00:00# and timevalue(now()) < #16:00:00#
'do stuff
Application.Wait(Now + #0:00:30#)
loop
At the beginning of your current code put Call Timer
Then include this in another sub:
Sub Timer()
Dim CountDown As Date
CountDown = Now + TimeValue("00:00:30")
Application.OnTime CountDown, "BTN_Start_Click"
End Sub
This will run your code every 30 seconds from when you start it.
This is another option if you just want to click it and leave it...
Sub Timer()
If TimeValue(CStr(Now)) >= TimeValue("9:00:00 AM") And TimeValue(CStr(Now)) <= TimeValue("4:00:00 PM") Then
Dim CountDown As Date
CountDown = Now + TimeValue("00:00:30")
Application.OnTime CountDown, "BTN_Start_Click"
Else
Dim CountTWO As Date
CountTWO = Now + TimeValue("00:00:05")
Application.OnTime CountTWO, "Timer"
End If
End Sub
Sub BTN_Start_Click()
Call Timer
'Your code here
End Sub
This will check to make sure the time is between 9 am and 4 pm... then every thirty seconds it will check again. If its between 9 am and 4 pm then it will run your code.
Related
I am trying to copy the selected combobox values into the adjacent cell, when I code for the same I am getting
Run time error 5.
Private Sub CommandButton1_Click()
Dim projworkbook As Workbook
Dim page1 As Worksheet
Dim lColumn As Long
Dim CopiedColName as String
Set projworkbook = ActiveWorkbook
Set page1 = projworkbook.Worksheets("Project_Creation")
lColumn = page1.Cells(13, Columns.Count).End(xlToLeft).Column 'Getting the last used column number
If lColumn > 26 Then
CopiedColName = Chr(Int((lColumn - 1) / 26) + 64) & Chr(Int((lColumn - 1) Mod 26) + 65) 'Converting the col number to col name
Else
CopiedColName = Chr(lColumn + 64)
End If
Me.Cells("CopiedColName" & 4).Text = Me.ComboBox1.Text '-> I am getting run time error at this line
End Sub
use:
Me.Range(CopiedColName & 4).Value = Me.ComboBox1.Text '-> I am getting run time error at this line
The basic idea of this (from the array names) are timesheets.
I have a Master Time sheet that has everyones' name on it, + the days.
The Concept is, open the http link from L/UBounds of array. Grab the data from the specific sheet, put it in my master sheet, close out that workbook, move on to next name.
Sub PassToProc()
Dim arr(4) As String
arr(0) = "https://sharepoint/Time Sheets/Jeff.xlsm"
arr(1) = "https://sharepoint/Time Sheets/Jonathan.xlsm"
arr(2) = "https://sharepoint/Time Sheets/Jim.xlsm"
arr(3) = "https://sharepoint/Time Sheets/Topher.xlsm"
arr(4) = "https://sharepoint/Time Sheets/Brandon.xlsm"
' Pass the array to function
UseArray arr
End Sub
Function UseArray(ByRef arrs() As String)
Dim name As String
Dim i As Integer
For i = LBound(arrs) To UBound(arrs)
If Cells(3, i + 4) <> "" Then
name = Cells(3, i + 4)
Select Case name
Case "Jeff"
Call InfoPuller(arrs, 0)
Case "Jonathan"
Call InfoPuller(arrs, 1)
Case "Jim"
Call InfoPuller(arrs, 2)
Case "Topher"
Call InfoPuller(arrs, 3)
Case "Brandon"
Call InfoPuller(arrs, 4)
End Select
End If
Next i
End Function
Sub InfoPuller(ByRef link() As String, i As Integer)
Dim Pay1 As String, Pay2 As String, PayPeriod As String
Dim wkb As Workbook
Pay1 = Format(Cells(3, 2), "m-dd")
Pay2 = Format(Cells(24, 1), "m-dd")
PayPeriod = "" & Pay1 & " -- " & Pay2 & ""
'Jeff (x,4) i = 0
'Jon (x,5) i = 1
'Jim (x,6) i = 2
'Topher (x,7) i = 3
'Brandon (x,8) i = 4
Set wkb = Workbooks.Open(link(i))
' Pay period 1 Fill in
For j = 5 To 11
ThisWorkbook.Sheets(PayPeriod).Cells(j, i + 4) = Workbooks.Open(link(i)).Worksheets(PayPeriod).Cells(j + 4, 9).Value
Next j
' Mileage / Bridge Week 1
Dim Mileage As Integer, Bridge As Integer, Store As Integer, Store2 As Integer
Dim MandB As String
Mileage = Workbooks.Open(link(i)).Worksheets(PayPeriod).Cells(28, 3).Value
Bridge = Workbooks.Open(link(i)).Worksheets(PayPeriod).Cells(29, 3).Value
MandB = Mileage & " / " & Bridge
ThisWorkbook.Sheets(PayPeriod).Cells(13, i + 4) = MandB
Store = Mileage
Store2 = Bridge
'Pay Period 2 Fill in
For j = 18 To 24
ThisWorkbook.Sheets(PayPeriod).Cells(j, i + 4) = Workbooks.Open(link(i)).Worksheets(PayPeriod).Cells(j + 1, 9).Value
Next j
' Mileage / Bridge Week 2
Mileage = Workbooks.Open(link(i)).Worksheets(PayPeriod).Cells(28, 4).Value
Bridge = Workbooks.Open(link(i)).Worksheets(PayPeriod).Cells(29, 4).Value
MandB = Mileage & " / " & Bridge
ThisWorkbook.Sheets(PayPeriod).Cells(26, i + 4) = MandB
Store = Store + Mileage
Store2 = Store2 + Bridge
MandB = Store & " / " & Store2
ThisWorkbook.Sheets(PayPeriod).Cells(31, i + 4) = MandB
wkb.Close SaveChanges:=True
End Sub
The problem is on this snippet.
For j = 5 To 11
ThisWorkbook.Sheets(PayPeriod).Cells(j, i + 4) = Workbooks.Open(link(i)).Worksheets(PayPeriod).Cells(j + 4, 9).Value
Next j
ThisWorkbook refers to the MasterSheet that the macro is running off of. PayPeriod is determined by the dates. Workbooks.Open(link(i)... is because if I try Workbooks(link(i)), it didn't like it (but it only opens up 1 copy, so I'm not worried about repeats).
As soon as it executes the Thisworkbook.sheets(PayPeriod), I hit the RTE-9 Subscript Out of Range error. The cells lines up, my pull data is right. I shortened the https link to just Sharepoint for privacy.
So on the excel sheet1 I have a list of information I need from the user.(there is a picture of it) On there we have starting time and execution time. This information is passed to sheet3 and I want the ending time to be change depending on the execution time. For example if the user inputs starting time= 1:00 pm and the excution time = 30 minutes. I would want the code to put at the endtime on sheet 3 = 1:30 pm. Here is the current code I have:
Sub findData()
Dim workflow As String
Dim finalrow As Integer
Dim i As Integer
With Sheets("Sheet1")
workflow = .Range("C5").Value
servergri = .Range("C9").Value
gridf = .Range("C9").Value
StartTime = .Range("c11").Value
End With
With Sheets("Sheet3")
finalrow = .Range("C" & Rows.Count).End(xlUp).Row
For i = 5 To finalrow
If .Cells(i, 3) = workflow And (.Cells(i, 4) = servergri Or .Cells(i, 5) = gridf) Then
.Rows(i).Insert
'Add new information to the new row.
'The new row number is still = i
.Cells(i, 3) = workflow
.Cells(i, 4) = servergri
.Cells(i, 6) = StartTime
.Cells(i, 3).Resize(2, 4).Interior.ColorIndex = 8
'If you only want to add one row then your should exit the loop
Exit For
End If
Next
End With
End Sub
This will do it, but you need to make sure the user only enters the time in minutes. EG "60" for 1 hour or "15" for 15 minutes. They should not enter a label.
Sub findData()
Dim workflow As String
Dim finalrow As Integer
Dim i As Integer
Dim StartTime as Date
Dim ExecutionTime as Long
With Sheets("Sheet1")
workflow = .Range("C5").Value
servergri = .Range("C9").Value
gridf = .Range("C9").Value
On Error Goto Next
StartTime = .Range("c11").Value
If Err Then
MsgBox "You didn't enter a valid start time.", vbExclamation
Exit Sub
End If
ExecutionTime = .Range("c16").Value
If Err Then
MsgBox "You didn't enter a valid execution time.", vbExclamation
Exit Sub
End If
On Error Goto 0
End With
With Sheets("Sheet3")
finalrow = .Range("C" & Rows.Count).End(xlUp).Row
For i = 5 To finalrow
If .Cells(i, 3) = workflow And (.Cells(i, 4) = servergri Or .Cells(i, 5) = gridf) Then
.Rows(i).Insert
'Add new information to the new row.
'The new row number is still = i
.Cells(i, 3) = workflow
.Cells(i, 4) = servergri
.Cells(i, 6) = StartTime
.Cells(i, 3).Resize(2, 4).Interior.ColorIndex = 8
'You don't mention where this time should go on Sheet 3, so I used Cell(i, 9)
'TimeSerial(Hours, Minutes, Seconds)
.Cells(I, 9).Value = StartTime + TimeSerial(0, ExecutionTime, 0)
.Cells(I, 9).NumberFormat = "hh:mm"
'If you only want to add one row then your should exit the loop
Exit For
End If
Next
End With
End Sub
I have a column of something that would be like XXX US, and I want to return XXX for the cell. I want to make a macro that deletes the whole column with one click. For some reason my ticker part of my code throws an error, but when i don't use a loop it works. Is there anything I can do?
Sub DEAS()
Dim cellText As String
Dim ticker As String
Dim i As Integer
i = 5
Do While i < 8000
cellText = Cells(i, 1).Value
ticker = Left(cellText, InStr(cellText, " ") - 1)
Cells(i, 1).Value = ticker
i = i + 1
Loop
End Sub
Give this a try:
Sub DEAS()
Dim cellText As String
Dim ticker As String
Dim i As Integer
i = 5
Do While i < 8000
cellText = Cells(i, 1).Value
If InStr(cellText, " ") > 0 Then
Cells(i, 1).Value = Split(cellText, " ")(0)
End If
i = i + 1
Loop
End Sub
Left(cellText, InStr(cellText, " ") - 1) will throw an error 5 "Invalid procedure call or argument" if the cellText doesn't contain a space. This is most likely due to encountering a value somewhere in A5:A8000 that either isn't in the expected format or is empty. In that case, Instr will return 0, which makes your call evaluate to Left(cellText, -1). You need to check the return value first (note that you can also use a For loop - IMHO more readable when your conditions are fixed):
Sub DEAS()
Dim cellText As String
Dim ticker As String
Dim i As Integer
Dim pos As Integer
For i = 5 To 8000
cellText = Cells(i, 1).Value
pos = InStr(cellText, " ")
If pos > 0 Then
ticker = Left(cellText, pos - 1)
Cells(i, 1).Value = ticker
End If
Next i
End Sub
I was running a VBA code in Excel 2007. I got the above mention run/Application error of 1004.
My code is
Public Sub LblImport_Click()
Dim i As Long, j As Long
Dim vData As Variant, vCleanData As Variant, vFile As Variant, sMarket As String
Dim wbkExtract As Workbook, sLastCellAddress As String, month As String
Dim cnCountries As New Collection
Application.ScreenUpdating = False
' Get the name of the Dataview Extract file to transform and the market name
vFile = "D:\DRX\" & "Norvasc_Formatted.xlsx"
sMarket = "Hypertension"
ThisWorkbook.Worksheets("Control").Range("TherapeuticMarket").Value = "Hypertension"
' Clear all existing data from this workbook
ThisWorkbook.Worksheets("RawData").Cells.ClearContents
' Create labels in Raw Data Sheet
ThisWorkbook.Worksheets("RawData").Cells(1, 1).Value = "Therapy Market"
ThisWorkbook.Worksheets("RawData").Cells(1, 2).Value = "Country"
ThisWorkbook.Worksheets("RawData").Cells(1, 3).Value = "Brand"
ThisWorkbook.Worksheets("RawData").Cells(1, 4).Value = "Corporation"
ThisWorkbook.Worksheets("RawData").Cells(1, 5).Value = "Molecule"
' Open Dataview extract, copy and clean data
Set wbkExtract = Workbooks.Open(vFile)
i = 2
Do While wbkExtract.ActiveSheet.Cells(1, i).Value <> ""
If UCase(Mid(wbkExtract.ActiveSheet.Cells(1, i).Value, 1, 3)) = "TRX" Then
month = Split(wbkExtract.ActiveSheet.Cells(1, i).Value, "/")(1)
If Len(month) = 1 Then
month = "0" + month
End If
ThisWorkbook.Worksheets("RawData").Cells(1, i + 4).Value = Mid(wbkExtract.ActiveSheet.Cells(1, i).Value, 1, 10) + month + "/" + Mid(Split(wbkExtract.ActiveSheet.Cells(1, i).Value, "/")(2), 3, 2)
End If
If UCase(Mid(wbkExtract.ActiveSheet.Cells(1, i).Value, 1, 3)) = "LCD" Then
month = Split(wbkExtract.ActiveSheet.Cells(1, i).Value, "/")(2)
If Len(month) = 1 Then
month = "0" + month
End If
ThisWorkbook.Worksheets("RawData").Cells(1, i + 4).Value = Mid(wbkExtract.ActiveSheet.Cells(1, i).Value, 1, 14) + month + "/" + Mid(Split(wbkExtract.ActiveSheet.Cells(1, i).Value, "/")(3), 3, 2)
End If
i = i + 1
Loop
wbkExtract.ActiveSheet.Cells(1, 1).EntireRow.Delete
vData = wbkExtract.ActiveSheet.Cells(1, 1).CurrentRegion.Value
wbkExtract.Close savechanges:=False
vCleanData = CleanRawData(vData, sMarket)
sLastCellAddress = ThisWorkbook.Worksheets("RawData").Cells(UBound(vCleanData, 1) + 1, UBound(vCleanData, 2)).Address(RowAbsolute:=False, ColumnAbsolute:=False)
ThisWorkbook.Worksheets("RawData").Range("A2:" & sLastCellAddress).Value = vCleanData
' Get List of Unique Countries
On Error Resume Next
For i = 1 To UBound(vCleanData, 1)
cnCountries.Add vCleanData(i, 2), vCleanData(i, 2)
Next i
On Error GoTo 0
ThisWorkbook.Worksheets("Market").Cells(1, 1).CurrentRegion.Clear
ThisWorkbook.Worksheets("Market").Cells(1, 1).Value = "Country"
ThisWorkbook.Worksheets("Market").Cells(1, 2).Value = "Group 1"
ThisWorkbook.Worksheets("Market").Cells(1, 3).Value = "Group 2"
ThisWorkbook.Worksheets("Market").Cells(1, 4).Value = "Group 3"
ThisWorkbook.Worksheets("Market").Cells(1, 5).Value = "Group 4"
ThisWorkbook.Worksheets("Market").Range("A1:G1").Font.Bold = True
For i = 1 To cnCountries.Count
ThisWorkbook.Worksheets("Market").Cells(i + 1, 1).Value = cnCountries.Item(i)
Next i
End Sub
Sounds like a broken code cache.
I've seen errors happen like this before in older format (xls) workbooks and it can be a sign of problems in the file overall.
Try the compile option suggested by #Scott Holtzman first. In some cases I've seen the recompile not work and if that happens just force a compile by making a change to the code. A trivial change is enough usually.
If that doesn't work then (to help disagnose a corruption issue) try copying the code into a new workbook and see what happens there. If it runs in the new sheet then I wouldn't waste more time on it and just rebuild the sheet, trust me it'll be quicker than messing about troublshooting the one you have.