VBA Running when Excel closed - vba

I have a challenge, for me at least, I cannot deal with apparently. Can somebody help me or advise on how to make the macro run when Excel is closed?
How can I make the macro run when the Excel is closed via VBA?
Sub Upload0()
' Upload Webpage content
Application.OnTime Now + TimeValue("00:00:15"), "Upload0"
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;http://cetatenie.just.ro/ordine/articol-11", Destination:=Range("A1"))
.Name = "CetatenieOrdine"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = True
.BackgroundQuery = True
.RefreshStyle = xlOverwriteCells
.SavePassword = True
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 1
.WebSelectionType = xlEntirePage
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
End With
' Deletes empty cells
Columns("A:A").Select
Selection.SpecialCells(xlCellTypeBlanks).Select
Selection.Delete Shift:=xlUp
' Adjust column width and delet useless rows
Rows("1:31").Select
Selection.Delete Shift:=xlUp
Range("B28").Select
Selection.End(xlDown).Select
Rows("17:309").Select
Selection.Delete Shift:=xlUp
End Sub
Many Thanks to all!

1: Define a boolean flag in a module Public blnClosedVBA as Boolean and set it to true in your VBA routine before closing the workbook. Then in your Workbook_BeforeClose event handler (under ThisWorkbook), do this:
If blnClosedVBA = True Then
Cancel = True 'Stops the workbook from closing
'Rest of your code here
blnClosedVBA = False ' Set so next time you try to close the workbook, it actually closes
'Workbook.Close or ThisWorkbook.Close - depends on your answer to my question below
That will run the routine only if you have triggered the close event yourself. At the end of the routine, setting the flag to False and triggering another Workbook.Close will close the workbook
2: Which workbook should it work for? Should it be 'ThisWorkbook' (the one from which you're running the code), 'ActiveWorkbook' (the one activated), or another one?

1.How can I make the macro run when the workbook is closed via VBA?
Short answer: you can't do that. Your code is part of the workbook and it can't run unless the workbook is loaded in Excel. You might be able to move the code to a separate add-in workbook that you elect to load by default (using "Excel Options|Add-Ins") when Excel starts. But Excel would still need to be running somewhere on your computer.
You could write a completely separate program that does what you want, writing the results of the web query into an Excel workbook. I'm assuming here that you want the workbook to always contain up-to-date data when it's referenced by yourself (when Excel is running of course) or some other resource. If you can acquire a copy of Visual Basic 6 (it may not be possible to achieve this legally) then that's mostly syntactically the same as VBA. Next closest would be VB.Net. This is going to be technically somewhat complex.
2.Also, I have issue making this macro working ONLY for one workbook but not active ones:
This one we can deal with: this line:
With ActiveSheet.QueryTables.Add(Connection:= _
means that the following code will always run against the worksheet that has the focus (i.e. is "active" - the sheet that would receive keyboard input if you typed something). That's what ActiveSheet does. Try replacing `ActiveSheet with something likeThisWorkbook.Sheet1, whereSheet1` is the name for the sheet that you see in the "Properties" window in the VBA editor where it says "(Name)".

Related

Pulling external data to next empty row as static, then repeating with next empty row? (Backing up Google Sheet data to Excel)

I have an Excel sheet that I would like to serve as the backup of a Google sheet, which I'll be clearing out periodically to prevent it from slowing down. I'm attempting to write a macro which, after a set period of time, will find the next empty row in the Excel sheet, activate the cell in column "A", and import the data from the Google Sheet. I don't want to "refresh" the data in Excel, because the plan is to delete the data in the Google Sheet every so often while the Excel sheet serves as a continuous record. I would simply like to pull the current Google Sheet data into the first cell of the next empty row, and schedule this to repeat.
Here's what I've been trying:
Sub addData()
newCell = Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Address
MsgBox newCell
Sheet1.QueryTables.Add(Connection:= _
"URL;googleSheetURL" _
, Destination:=Range(newCell))
.PostText = "transaction-data_1"
.Name = False
.FieldNames = False
.RefreshStyle = xlInsertDeleteCells
.RowNumbers = False
.FillAdjacentFormulas = False
.HasAutoFormat = False
.RefreshOnFileOpen = 2
.BackgroundQuery = False
.TablesOnlyFromHTML = True
.SaveData = True
.Refresh BackgroundQuery:=False
.UseListObject = False
End With
End Sub
Where googleSheetURL is replaced with the published link of the sheet.
I just keep getting errors, debug mode highlights the Refresh BackgroundQuery line. I disabled background refresh because I didn't want the queries to update once I pulled them. Does anyone have any insight?
This code doesn't compile. You're missing a With in front of Sheet1:
Sub addData()
newCell = Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Address
With Sheet1.QueryTables.Add(Connection:= _
"URL;googleSheetURL" _
, Destination:=Range(newCell))
.PostText = "transaction-data_1"
.Name = False
.FieldNames = False
.RefreshStyle = xlInsertDeleteCells
.RowNumbers = False
.FillAdjacentFormulas = False
.HasAutoFormat = False
.RefreshOnFileOpen = 2
.BackgroundQuery = False
.TablesOnlyFromHTML = True
.SaveData = True
.Refresh BackgroundQuery:=False
.UseListObject = False
End With
End Sub

How to turn on row numbers and turn off field names will using QueryTable for Text Import

I need to import a text file using a QueryTable object and return row numbers along with the data. However, setting RowNumbers property to True doesn't seem to have an effect.
Setting FieldNames also does not appear to matter (field name always show), but I can live with that for purposes of my use case.
Example using publicly available data:
Sub ReadTestData()
Set QT = ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;http://samplecsvs.s3.amazonaws.com/Sacramentorealestatetransactions.csv", _
Destination:=Range("$A$1"))
With QT
.Name = "TestData"
.FieldNames = False 'doesn't seem to matter
.RowNumbers = True 'doesn't seem to matter
.PreserveFormatting = True
.RefreshStyle = xlInsertDeleteCells
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileCommaDelimiter = True
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End Sub
I'm working in Excel 2010. Why don't these flags seem to do anything?
According to this site, .RowNumbers will not work until you refresh:
"Setting this property to True doesn't immediately cause row numbers to appear. The row numbers appear the next time the query table is refreshed, and they're reconfigured every time the query table is refreshed"
Also, on this site there is the following note concerning the row numbers checkbox (which turns the .RowNumbers property on and off when adjusting the External Data Range Properties)
NOTE: This check box is not available for an imported text file, XML file, or Web query.

Copy table (with no id) from password protected website

I would like to retrieve a table from my bank's website, and paste it in the same format in an excel sheet.
Thanks to a few posts on this very useful website, I managed to write a vba code that automatically :
Open the Internet Explorer windows
Fills in the Log-in and Password details
Clicks on the submit Button, thus connecting me to my bank account
Clicks on the "previous day transaction report" button, thus generating the report
And finally shows this report in Internet Explorer
Now my problem is :
How can I copy this report (which is a table) and paste it in an excel sheet, with the Exact same format as it appears on the website ?
On the html code of the website page, this table has no "id". But it has a class, called "report". And it is the only one who has this class.
I suppose I have to use this :
IE.document.getElementsByClassName("report")(0).outerHTML
But I am not sure how to use it... Basically the simplest thing for me would be to write a last portion of code that copies the report to the clipboard, and paste it with the same format on the spreadsheet.
Any idea how I could do that?
i recorded a macro to get the code, using this should copy the table for you. I think its the best way for you. You have to change the URL and the webtable. This will copy it.
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;http://THE URL AFTER LOGIN WITH THE TABLE", _
Destination:=Range("$A$1"))
.CommandType = 0
.Name = "SEQUENCE OF URL"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlSpecifiedTables
.WebFormatting = xlWebFormattingNone
.WebTables = "11"
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
End With
Lets make this work!! :) step by step.
You are right. Fill a form using it.
Try open the page, press F12 and use the console to make sure everything is right.
To fill
document.getElementById("Id").value = "xxxxx"
document.getElementById("Id2").value = "pass"
To click
document.getElementById("name").click()
Set objie = CreateObject("InternetExplorer.Application")
objie.Visible = True
With objie
.AddressBar = False
.StatusBar = False
.MenuBar = False
.Toolbar = 0
.NAVIGATE "http://www.loginpage.com"
While .BUSY
Wend
Do While .READYSTATE <> 4: DoEvents: Loop
'first you login
Set htmldoc = .document
htmldoc.getElementById("UserId").Value = "login"
htmldoc.getElementById("Password").Value = "pass"
htmldoc.getElementById("submit-btn").Click
End With
Try using this one, its first step... Makes sense to you? Im new here, so i will do my best

VBA Excel QueryTables.add .Refresh BackgroundQuery Error

Sub Macro1()
Dim URL As String
Dim Path As String
Dim i As Integer
For i = 2 To 50
If Range("Prices!E" & i).Value <> 1 Then
URL = Range("Prices!D" & i).Text
Path = Range("Prices!F" & i).Text
End If
Sheet19.Activate
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;" & URL _
, Destination:=ActiveSheet.Range("$A$1"))
.Name = _
"" & Path
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlEntirePage
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
//'In the Line above the above
//'Run time error '1004
//'An unexpected error has occured
End With
Next i
End Sub
The code above creates an error at the specified line. A google search on .Refresh BackgroundQuery shows that it is picky in its functionality in loops. Simply deleting the line makes nothing show up in excel.
With the current error message the code works fine for the first i value and then breaks.
For Answer and comments-
TLDR: .Refresh BackgroundQuery:=False will fail if your query input is invalid or malformed. The problem in this case was the for...next loop was calling cells to use as url's that hand no values in them. However it will fail anytime the query is malformed.
All the previous lines inside the With statement are setting properties.
the .Refresh BackgroundQuery := False is a method call.
The refresh is supposed to refresh the results.
The background Query is for when quering SQL data and is optional so I think you can leave it off and just have .Refresh
Query Table Refresh Method Help Link
Edit
It would appear that there is something wrong with the URL and when it goes to refresh it is unable to do it. could be a proxy issue, or not connected to the network, or the URL does not exist.
The only way to resolve this issue is to delete the active query table after each iteration. A useful example solution provides:
https://social.technet.microsoft.com/Forums/office/en-US/956dc1b6-bd37-4b97-a042-ba2a37f729b6/removing-querytables-and-leaving-the-results?forum=excel
I'm not sure why my fix worked, but here it is:
I also used querytables.add within a for loop, and I was adding .asc files. This error was only popping up after the last addition--so my program essentially did what I wanted it to, but it would interrupt function. On the last run through the For loop, I removed the .Refresh BackgroundQuery:=False statement. It was necessary for it to paste my data for all the previous runs through the For loop.
Basically I replaced this:
.Refresh BackgroundQuery:=False
With this:
If Index = ctr Then
Else
.Refresh BackgroundQuery:=False
End If

Recorded Macro in Excel fails on run

Sub Macro3()
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;http://..." _
, Destination:=Range("Sheet6!$G$23"))
''// The line above fails with the error:
''// "Run-time error '-2147024809 (80070057)':
''// The destination range is not on the same worksheet
''// that the Query table is being created on."
.Name = _
"?tmp=toolbar_FlvTube_homepage&prt=..."
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlEntirePage
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
End With
End Sub
The recorded macro fails as described in the comment.
You recorded the macro while Sheet 6 was active, but are now trying to run it on a different sheet. To run the macro for the current active sheet, simply change the code as follows:
Sub Macro3()
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;http://..." _
, Destination:=ActiveSheet.Range("$G$23"))
...
End With
End Sub
Edit: (in response to comment):
I need to be able to paste the results of the query to a different sheet then the active one since the macro can be run at any time and must be paste to the same location everytime. Perhaps there is a way to change your active sheet with code?
The error happens when the two sheets are different, so if you want the magic to happen on a particular sheet, you should specify that sheet instead of using ActiveSheet. The following code would always place the QueryTable on Sheet6:
Sub Macro3()
With Sheet6.QueryTables.Add(Connection:= _
"URL;http://..." _
, Destination:=Sheet6.Range("$G$23"))
...
End With
End Sub