Editing dates in a URL for excel via - vba

I am a fairly new to vba coding and would appreciate some help as I play around with some code. I am trying to edit a URL to make searching for historical exchange rates dynamic
original code:
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;http://www.x-rates.com/historical/?from=USD&amount=1&date=2017-04-20", _
Destination:=Range("A1"))
.PostText = "currency_exchange_practice"
My new code that doesn't work:
Dim dateday, datemonth, dateyear As Long, fulldate As Variant
Columns("A:D").ClearContents
dateday = Day(Range("G2"))
datemonth = Month(Range("G2"))
dateyear = Year(Range("G2"))
fulldate = dateyear & "-" & datemonth & "-" & dateday
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;http://www.x-rates.com/historical/?from=USD&amount=1&date=" & fulldate & "", _
Destination:=Range("A1"))
.PostText = "currency_exchange_practice"
It is also erasing all my data in cells g2, including a button I have made that are not in cells A:D. Please and thank you for your help!!

I think the issue is with your use of Month
Month for April will return 4 not 04 so when you pass in fulldate to the URL you are passing in 2017-4-20 instead of 2017-04-20. If I pass in fulldate as you have it, I get nothing returned.
To remedy this issue I would first declare your date parts as strings so we can use the Format function. An important note here is that you must declare each variable with a datatype. As you have it written, dateday and datemonth are Variants because they are not explicitly given a data type.
Dim dateday As String, datemonth As String, dateyear As String, fulldate As String
Then you can do this:
dateday = Format(Day(Range("G2")), "00")
datemonth = Format(Month(Range("G2")), "00")
Now, fulldate will look like 2017-04-20 and should work.
I did confirm that the website you are using expects a two digit value for the day as well.
I am not sure why it would be erasing anything in column G except if your query table somehow overlaps it when it is placed in A1.

Related

Why does my SQL statement not find a match with the WHERE statement below?

I'm attempting to pull data from my MS Access database via an Excel SQL statement. It does NOT give me any errors, however it also does not pull the data I'm searching for.
If items(u, 1) is text (ex. 308-203BL), then it works perfectly.
I've tried both comparing them as text and as numerical, but neither way find any matches when items(u, 1) is 19310.
This compares it as text...
LEFT(Item," & Len(items(u, 1)) & ") = '" & items(u, 1) & "'"
this compares it as numerical...
VAL(LEFT(Item," & Len(items(u, 1))) & ") = " & items(u, 1)
I have verified that there are records in the DB that match the given criteria.
items() is an array populated from a 1 column table on the sheet by items = Range("Items").Value.
Using these two SKU's as examples, the first working, the second not, the array would be as follows. .
SKU by SKU, they're fed into the SQL as below.
With the input in the example, the output I receive is an array populated only the sales for the second item. The order I put the SKU's in the table doesn't change that result. I have tested it with multiple SKU's, and no matter how many I use, it returns the proper information, with the exception of not returning any results for any numerical SKU's.
The field for Item in the DB is a short text, which is why I used '" & items(u, 1) & "'" to convert the SKU to text when I was trying to match it as text, and Val() to convert the field to a value when trying to match it as a number. Both gave me 0 record counts in the function, but did not give me a data type error.
Below is the portion of my code which determines the SQL string, and a bit afterwords which basically stuffs it into a UDF which pulls the info from the DB and puts it into an array for me. Aside from not finding a match when items(u,1) is numerical, it works perfectly.
DBString = "SELECT Invoice, Line, Inv_Date, Sales_Order, SOLine, SO_Date, CustID, Item, Part_Description, Ship_Qty, Price, Ext_Sales FROM `" & Year(tabledate) & "-" & Format(tabledate, "mm") & "` WHERE Inv_Date BETWEEN #" & Sdate & "# AND #" & Edate & "# AND LEFT(Item," & Len(items(u, 1)) & ") = '" & items(u, 1) & "'"
SalesHolder = PullFromDB(DBString, SGMDB)
I've also tried the below code instead, to force it to compare as a number instead of text, which also doesn't give me any errors, but doesn't find a match.
DBString = "SELECT Invoice, Line, Inv_Date, Sales_Order, SOLine, SO_Date, CustID, Item, Part_Description, Ship_Qty, Price, Ext_Sales FROM `" & Year(tabledate) & "-" & Format(tabledate, "mm") & "` WHERE Inv_Date BETWEEN #" & Sdate & "# AND #" & Edate & "# AND VAL(LEFT(Item," & Len(items(u, 1))) & ") = " & items(u, 1)
SalesHolder = PullFromDB(DBString, SGMDB)
Below is the UDF itself which pulls the info from the DB. It works quite nicely.
Function PullFromDB(DBStr As String, DBLoc As String) As Variant
Dim TheDB As Recordset, DBHolder() As Variant
Set TheDB = OpenDatabase(DBLoc).OpenRecordset(DBStr)
If TheDB.RecordCount = 0 Then GoTo theexit
TheDB.MoveLast
TheDB.MoveFirst
ReDim DBHolder(0 To TheDB.RecordCount, 1 To TheDB.Fields.Count) As Variant
For k = 1 To UBound(DBHolder, 2)
TheDB.MoveFirst
For j = 0 To UBound(DBHolder)
If j = 0 Then
DBHolder(j, k) = TheDB.Fields(k - 1).Name
Else
DBHolder(j, k) = TheDB.Fields(k - 1).Value
TheDB.MoveNext
End If
Next j
Next k
theexit:
TheDB.Close
Set TheDB = Nothing
PullFromDB = DBHolder
On Error GoTo -1
End Function
The expected result is to populate the array SalesHolder with the information that matches the criteria.
What am I missing? I'm going blind trying to find it.
Thank you all for your responses to this, it turns out I was completely hunting for the wrong problem. The code I posted was actually correct, the issue was with the format of Inv_Date field in the DB. I had mistakenly entered the last couple of months as text instead of date, so the WHERE Inv_Date BETWEEN #" & Sdate & "# AND #" & Edate & "# portion of my SQL didn't match anything.
I hadn't identified that this was the issue earlier due to the timing of the sales of the SKU's themselves, which was purely coincidence. When I expanded the dates range, I found that it did return results for the numerical SKU, but both numerical and text SKU's cut off two months ago.
Thank you again!

Find the earliest date in VBA

I have a lot of dates in column D. I need to find the student with the earliest date, and show the following information in a messagebox:
Sub Finddate()
Dim Mn As Integer
Mn = Application.Match(Application.Min(Range("D2:D18288")), Range("D2:D18288"), 0)
MsgBox ("For the student with the earliest date (" & Range("D" & Mn) & ") the following information applies: " & Range("k" & Mn) & ", " & Range("L" & Mn) & " and " & Range("M" & Mn))
End Sub
However when i run the Macro it shows the wrong date. The earliest date in the sheet is 31-08-1996, but it says the earliest date is 01-02-2010 and if i write =min(D2:D18288) in Excel it finds the right date. But i need it to work in VBA as well. And if i change min to max it also finds the wrong date. But if i instead write:
Mn = Application.Match(Application.Max(Range("D2:D18288")), Range("D2:D18288"))
It shows the right date but i need to find the min date not the max date and when i change max to min I get a type mismatch error. I really don’t know what is wrong really hope someone can help me!
Your indexing is off by 1 ................because the data starts out a D2 rather than D1, Mn points to the cell just above the minimum.
When something like this happens, try to replicate the result, using a small sample. E.g. this one, hoping to return Peter6 for the smallest info:
Option Explicit
Public Sub TestMe()
Dim dateRanges As Range
Set dateRanges = Range("D1:D11")
Dim mn As Variant
With Application
mn = .Match(.Min(dateRanges), dateRanges, 0)
End With
MsgBox Range("E" & mn).Value2
End Sub
Once it works, try to fix it with your big example.
You will probably notice that mn should not be Integer as far as Integer is up to 32767 and this parsed to a date is 16-September-1989, which is long time ago. In your case it is not an error, because you are not referencing mn directly to a date, but it may happen at a later.

Function not working because I use dates?

I’m trying to write a function that depends on dates, but I can’t get it to work. Excel keeps telling me that a value that is used in this formula have the wrong data type. So it has to be the date, because I have another function that is exactly the same except for the add of a datevalue.
Someone writes a date in the Excel-cell C10 and then I wan’t the function to summarize certain numbers (predicted inflation rates, column P) from a table (on another sheet in the same workbook) in which it depends on begin-dates (column I) and end-dates (column J).
I’ve checked that Excel interprets cell C10 as a date, it does but with a serial number.
But I don’t see why that is a problem since I use it to compare with other dates (serial numbers)?
Public Function FetchFactorInflation(Product As String, ArgName As String) As Double
Dim Datum As Date
Datum = DateValue(Worksheets("InputTariff").Range("C10").Value)
Dim MinDatum, MaxDatum As Double
MinDatum = "<=" & Datum
MaxDatum = ">=" & Datum
FetchFactorInflation = Application.SumIfs(Worksheets("tariff").Range("P:P"), _
Worksheets("tariff").Range("I:I"), MinDatum, _
Worksheets("tariff").Range("J:J"), MaxDatum, _
Worksheets("tariff").Range("K:K"), Product, _
Worksheets("tariff").Range("L:L"), ArgName)
End Function
The wrong data type comes from here:
MaxDatum = ">=" & Datum
MaxDatum is a double, and you are giving >= to it. It cannot be converted to a Double. Try a way around.
The quickest solution would be to write like this:
Dim MinDatum, MaxDatum
instead of
Dim MinDatum, MaxDatum As Double
Thus MaxDatum would be easily converted to what you need, because it would be variant as well as MinDatum.

Getting the date format in VBA in the correct form

I am trying to reference a file that has the date of the previous Friday at the end in the form of mm.dd.yy.
I need to now take that date and add it to the end of a string, to end of a string in order to open select the other workbook. This is what I have right now.
File Name:
Submittals Wk Ending 06.02.17.xlsx
This is what I have so far
Dim wrbk As String
Dim weekdate As String
range("a1").value="=TODAY()-WEEKDAY(TODAY())-1"
weekdate = Range("a1").Value
'range("b1").value="06.02.17"
'weekdate = Range("b1").Value
msgbox weekdate 'use to check what the date format is
wrbk = "Submittals Wk Ending " & weekdate
Windows(wrbk & ".xlsx").Activate
When I read it from B2 with the typed in format of 06.02.17 it works, however no matter what I do, I cannot get it to read it from A1 because it changes the format to m/d/yyyy. I have tried to copy it and paste as value. Nothing seems to work.
I have the other workbook open as well when I try to run it.
Any ideas? Thanks!
To get the previous Friday of any date, try below UDF. This should work fine if the Date NumberFormat is same as your System's Date format. The key is the CDate() which converts according to System's Date format which Office apps defaults to.
Option Explicit
Function GetLastFridayDate(AnyDate As Variant) As Date
Dim dInput As Date, dLastFriday As Date
dInput = CDate(AnyDate)
dLastFriday = dInput - Weekday(dInput) + vbFriday - IIf(Weekday(dInput) > vbFriday, 0, 7)
GetLastFridayDate = dLastFriday
End Function
Try
Range("A1").Value = Format$(Date - Weekday(Date) - 1, "MM.DD.YY")

Pick date from cell and use as a file handle while saving

A2=201604
I am trying to pick up value from a Cell(Date) and use the same for saving the file.
But while saving instead of the date a value is being printed, see code below:
Dim part1 as string
part1 = Range("A2").Value
ActiveWorkbook.SaveAs Filename:=ThisWorkbook.Path & "\xxx- " & Format(part1, "MMM-YYYY") & ".xlsx" , FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
201604 is not a date. It is just a number.
You could use something like
myDate = "01/" & right(a2,2) & "/" left(a2,4)
string yourAnswer = format(myDate, "MMM-YYYY")
The problem is you're prematurely casting the Date into a String by using the part1 variable, so the 'date' is already broken and not recognisable as a date by the time it hits your Format() call.
Either declare part1 as a Date or just skip the whole part1 declaration and insert Range('A2').Value directly into the Format() call.