I have two tables, one (DATES) is a list of 25 dates. The second (RatingsBackDated) is a list of 13,000 names, ratings, IDs and dates. I am trying to create a loop function that goes through and appends the last rating nearest to a date to a table (tblCoDtRtgs). Currently, my code goes through and returns the data from 25 fields, correctly returning the nearest/last data from each of the 25 dates in table DATES. I need it to provide the information for all 13,000. What am I doing wrong?
Thank you!
-J.
Public Function PopulateTableOfRatingHistory()
Dim dbs As DAO.Database
Set dbs = CurrentDb
Dim dtDate As Date 'snapshot date
Dim sqlAppend As String
Dim sqlQueryLastRating As String
Dim qdf As DAO.QueryDef
Dim rs1 As DAO.Recordset
Dim rs2 As DAO.Recordset
Set rs1 = dbs.OpenRecordset("DATES") 'check this to make sure it imports the table values
rs1.MoveFirst
Do While Not rs1.EOF
'get the date value to use as a parameter
dtDate = rs1.Fields(1).Value ' get the date value to lookup
'use the date parameter to run the SQL for the last rating as of the given date
sqlQueryLastRating = "SELECT RatingsBackDated.name, RatingsBackDated.CoID, Last(RatingsBackDated.Rating) AS LastOfRating, Last(RatingsBackDated.Date) AS LastOfDate " & _
"FROM RatingsBackDated " & _
"WHERE (((RatingsBackDated.Date)<= #" & dtDate & "#)) " & _
"GROUP BY RatingsBackDated.name, RatingsBackDated.CoID;"
Debug.Print sqlQueryLastRating
Set rs2 = dbs.OpenRecordset(sqlQueryLastRating)
'append the query result to a table
sqlAppend = "INSERT INTO tblCoDtRtgs ( CoID, SnapDate, Rating, RatingDate ) VALUES (" & rs2.Fields(1) & ", #" & dtDate & "#, " & rs2.Fields(2) & ", #" & rs2.Fields(3) & "#);"
dbs.Execute sqlAppend
rs2.Close
rs1.MoveNext
Loop
rs1.Close
Set rs1 = Nothing
Set rs2 = Nothing
Set dbs = Nothing
End Function
Related
I have a large spreadsheet I was asked to edit. Basically wherever the data was pulled from, it created several duplicates of individuals names, country, start dates, and end dates. Would it be possible to get the start and stop dates in adjacent cells and remove the duplicate data?
I have provided a screen shot. Manually copying, pasting, and deleting would take a very long time since this spreadsheet has over 2300 rows with approximately 50% being duplicates that will need edited.
thanks
VBA shouldn't be necessary here, just add a new column with the formula:
=CONCATENATE(C1,D1)
Replace the column letters with your column letters for Start Date and End Date.
You can then use Excel's remove duplicates function on the new column (Data -> Remove Duplicates)
Using SQL is suitable.
Sub myQuery()
Dim strSQL As String
Dim strTable As String
Dim Ws As Worksheet
strTable = "[" & ActiveSheet.Name & "$]"
strSQL = "SELECT NAME, COUNTRY, MIN([Start Date]) as [Start Date] , max([End Date]) as [End Date] "
strSQL = strSQL & " FROM " & strTable & " "
strSQL = strSQL & " Where not isnull(NAME) "
strSQL = strSQL & " Group by NAME, COUNTRY "
Set Ws = Sheets.Add
exeSQL strSQL, Ws
End Sub
Sub exeSQL(strSQL As String, Ws As Worksheet)
Dim Rs As Object
Dim strConn As String
Dim i As Integer
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & ThisWorkbook.FullName & ";" & _
"Extended Properties=Excel 12.0;"
Set Rs = CreateObject("ADODB.Recordset")
Rs.Open strSQL, strConn
If Not Rs.EOF Then
With Ws
.Range("a1").CurrentRegion.ClearContents
For i = 0 To Rs.Fields.Count - 1
.Cells(1, i + 1).Value = Rs.Fields(i).Name
Next
.Range("a" & 2).CopyFromRecordset Rs
.Columns.AutoFit
End With
End If
Rs.Close
Set Rs = Nothing
End Sub
I am checking in the table "weekly data" for a specific date stored in the first row of the table "daily data":
Private Sub Data_Update_Click()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim rstw As DAO.Recordset
Set db = Application.CurrentDb
Set rst = db.OpenRecordset("Data daily", dbOpenDynaset)
Set rstw = db.OpenRecordset("Data Weekly", dbOpenDynaset)
With rst
.MoveFirst
Dim date_check As Date
date_check = DLookup("[ID test]", "Data Weekly", "[weekly date] = '" & .Fields("daily date") & "'")
.........
The criteria is causing the problem, cannot find the right syntax.
Use:
date_check = DLookup("[ID test]", "Data Weekly", "[weekly date] = #" & Format(.Fields("daily date").Value, "yyyy\/mm\/dd") & "#")
but date_check must be a Variant as DLookup can return Null.
Suppose I have a table in Excel with two columns (Name, Rate) (say, this table's name tExcel). Table starts at cell (2,1), and Date is static (in cell (1,1))
I want to insert those values into SQL Server 2008 tRate table with following logic
insert tRate(ID, Rate, Date)
select
s.ObjectID, e.Rate, Date -- date comes from cell(1,1). DateType is smalldatetime
from
tExcel e, tSecurity s
where
e.Name = s.Number
I've created a connection
Sub disp_cust()
Dim adoCN As ADODB.Connection
Dim sConnString As String
Dim sSQL As String
Dim lRow As Long, lCol As Long
Set cn = New ADODB.Connection
sConnString = "Provider=sqloledb;Server=xxx;Database=xxx;User Id=xxx;Password=xxx"
Set adoCN = CreateObject("ADODB.Connection")
adoCN.Open sConnString
adoCN.Close
Set adoCN = Nothing
End Sub
Thanks for help.
EDIT to #jaimetotal answer
sql= "insert tRate(ID, Rate, Date) SELECT s.ObjectId ," & Replace(Row.Cells(2).Value, ",", ".") & ",'" & defaultDate & "' FROM tSecurity s where s.number = '" & row.Cells(1).Value & "'; "
For this sample, I assume that tExcel.Number is the first column and tExcel.Rate is the second. The idea here is to do a for each row in the table (or range) and create an insert/select statement.
Dim rng as Range
Dim defaultDate As string
Dim sql as string, bulkSql as string
Set rng = Range("A1:XX") -- Range of the table.
defaultDate = Format(Range("A2").Value, "yyyy/mm/dd")
bulkSql = ""
'generated sample: insert tRate(ID, Rate, Date) SELECT s.ObjectId, '0.15', '2015/08/24' FROM tSecurity s where s.Number = '007'
For Each row In rng.Rows
sql= "insert tRate(ID, Rate, Date) SELECT s.ObjectId " & "','" & row.Cells(2).Value & "','" & defaultDate & "' FROM tSecurity s where s.number = '" & row.Cells(1).Value & "'; "
bulkSql = bulkSql & sql
Next row
adoCn.Execute bulkSql, , adCmdText
Edit:
If you really mean a table, than you can use this sample based from here.
Dim lo As Excel.ListObject
Dim ws As Excel.Worksheet
Dim lr As Excel.ListRow
Set ws = ThisWorkbook.Worksheets(1)
Set lo = ws.ListObjects("tExcel")
'The other code from the previous sample. Use the following ForEach instead
For Each lr In lo.ListRows
Dim Rate as String
Dim Number as String
Rate = Intersect(lr.Range, lo.ListColumns("Rate").Range).Value
Number = Intersect(lr.Range, lo.ListColumns("Number").Range).Value
'Generate the query from these values instead
Next lr
I tried to translate a code from VBA excel to access. My data is a column of prices and I want to compute the returns.
This is the original VBA code in excel:
DerCol = Cells(T.Row, Columns.Count).End(xlToLeft).Column
Cells(T.Row, DerCol + 1) = "Returns"
For i = T.Row + 2 To T.End(xlDown).Row
Cells(i, DerCol + 1) = Application.WorksheetFunction.Ln(Cells(i, T.Column)) - Application.WorksheetFunction.Ln(Cells(i - 1, T.Column))
Next i
To get an idea of the output that I have in excel, click here.
In Access, I created a new column next to the prices' column and I would like to fill in exactly like in excel:
Sub vardaily()
Dim db As Database, T As Object, DerCol As Integer, y As TableDef
Dim rs As DAO.Recordset, i As Integer, strsql As String
'idea = SELECT prices FROM dailypricing, then creates newtable "VAR", copy and prices, compute historical and parametric VAR '
'create a new table var_daily'
Set db = CurrentDb()
'insert the pricing date and the prices from dbo_daily'
db.Execute "CREATE TABLE VAR_daily" _
& "(PricingDate CHAR, Price Number);"
'where clause to select the same traded product only'
db.Execute " INSERT INTO VAR_daily " _
& "SELECT PricingDate, Price " _
& "FROM dbo_PricingDaily " _
& "WHERE IndexId = 1;"
db.Execute " ALTER TABLE VAR_daily " _
& "ADD COLUMN Returns Number;"
'sql request to store prices'
strsql = "SELECT First(Price) as FirstPrice, Last(Price) as EndPrice FROM VAR_daily;"
'dao.recordset of the store prices'
Set rs = db.OpenRecordset(strsql, dbOpenDynaset)
'loop to change the prices'
For i = 2 To i = rs.RecordCount
rs.Edit
rs!Price(i) = Log(rs!Price(i)) - Log(rs!Price(i - 1))
rs.Update
Next i
db.Execute "INSERT INTO VAR_daily " _
& "(Returns) VALUES " _
& "(" & rs![Price] & ");"
End Sub
I have the following table that you can see here
I can not manage with the loop. I have no item in my collection at the end.
I looked at other example of loops like here but I did not find how to make an iteration with the last result.
Sorry, I really am a beginner in Ms Access and SQL. I started this week so I apologize if my question is very basic.
EDIT: I added the images and I replaced Firsttransaction and Lasttransaction by "FirstPrice" and "EndPrice".
EDIT2: Thanks to my new privilege, I can share a sample for those who are interested.
I have updated your complete code to what it should be. Again, I don't have an Access database handy to test it but it compiles and should work:
Sub vardaily()
Dim db As Database
Dim rs As DAO.Recordset, i As Integer, strsql As String
Dim thisPrice, lastPrice
'idea = SELECT prices FROM dailypricing, then creates newtable "VAR", copy and prices, compute historical and parametric VAR '
'create a new table var_daily'
Set db = CurrentDb()
'insert the pricing date and the prices from dbo_daily'
db.Execute "CREATE TABLE VAR_daily" _
& "(PricingDate CHAR, Price Number);"
'where clause to select the same traded product only'
db.Execute " INSERT INTO VAR_daily " _
& "SELECT PricingDate, Price " _
& "FROM dbo_PricingDaily " _
& "WHERE IndexId = 1 " _
& "ORDER BY PricingDate;"
db.Execute " ALTER TABLE VAR_daily " _
& "ADD COLUMN Returns Number;"
'sql request to retrieve store prices'
strsql = "SELECT * FROM VAR_daily ORDER BY PricingDate;" ' just get all fields
'dao.recordset of the store prices'
Set rs = db.OpenRecordset(strsql, dbOpenDynaset)
'loop to change the prices'
lastPrice = rs.Fields("Price") ' get price from first record and remember
rs.MoveNext ' advance to second record and start loop
While (Not rs.EOF())
thisPrice = rs.Fields("Price")
rs.Edit
rs!Returns = Log(thisPrice) - Log(lastPrice)
rs.Update
lastPrice = thisPrice ' remember previous value
rs.MoveNext ' advance to next record
Wend
End Sub
I am trying to run an append query to update a table based on the first 30 records for parameters in an sql statement. All of the data resides in an Access 2010 database, and I would like to run the query based off of a button on a form.
I am new to vba and assembled the following code based off of posts.
Option Compare Database
Private Sub Command3_Click()
Dim sql As String
Dim i As Integer
Dim j As Integer
Dim rst As DAO.Recordset
Dim dbs As DAO.Database
Dim strTerritory As String
Set dbs = CurrentDb
strTerritory = "Alex Hernandez"
strSQL = "INSERT INTO tblWeather30DayMovingFinal ( NEW, RptdDate, [Clm Nbr], WeatherLimit ) SELECT TOP 30 tblWeather30DayMoving.[NEW], tblWeather30DayMoving.[RptdDate], tblWeather30DayMoving.[Clm Nbr], 1 AS WeatherLimit FROM tblWeather30DayMoving WHERE (((tblWeather30DayMoving.NEW)= strTerritory ) AND ((tblWeather30DayMoving.RptdDate) Between #" & i & "/1/" & j & "# And #" & i & "/28/" & j & "#)); "
Set rst = dbs.OpenRecordset("tblWeather30DayMoving", dbOpenTable)
With rst
For j = 2003 To 2013
For i = 1 To 12
If Not (rst.EOF And rst.BOF) Then
.MoveFirst
Do
CurrentDb.Execute strSQL
.MoveNext
Loop Until .EOF
End If
Next i
Next j
End With
Set rst = Nothing
End Sub
I receive the following error message. I am trying to figure out how to get the loop to fill my date references in the sql.
Run-time error '3075':
Syntax error in date in query expression '(((tblWeather30DayMoving.NEW)- strTerritory ) AND ((tblWeather30DayMoving.RptdDate) Between #0/1/0# And #0/28/0#)'.
Any idea how to pass i and j to the sql statement instead of the 0's that are currently showing?
You are setting the strSQL string outside of your loop.
At this point, the values of i and j are 0.
You need to assign value to strSQL inside of the second loop:
For j = 2003 To 2013
For i = 1 To 12
strSQL = "INSERT INTO tblWeather30DayMovingFinal ( NEW, RptdDate, [Clm Nbr], WeatherLimit ) SELECT TOP 30 tblWeather30DayMoving.[NEW], tblWeather30DayMoving.[RptdDate], tblWeather30DayMoving.[Clm Nbr], 1 AS WeatherLimit FROM tblWeather30DayMoving WHERE (((tblWeather30DayMoving.NEW)= strTerritory ) AND ((tblWeather30DayMoving.RptdDate) Between #" & i & "/1/" & j & "# And #" & i & "/28/" & j & "#)); "
If Not (rst.EOF And rst.BOF) Then
.MoveFirst
Do
CurrentDb.Execute strSQL
.MoveNext
Loop Until .EOF
End If
Next i
Next j
I did it in notepad and not tested, but here is the idea:
Option Compare Database
option explicit
Private Sub Command3_Click()
Dim sql As String, sql2 as string
Dim i As Integer
Dim j As Integer
Dim rst As DAO.Recordset
Dim dbs As DAO.Database
Dim strTerritory As String
Set dbs = CurrentDb
strTerritory = "Alex Hernandez"
sql = "INSERT INTO tblWeather30DayMovingFinal ( NEW, RptdDate, [Clm Nbr], WeatherLimit ) " & _
"SELECT TOP 30 tblWeather30DayMoving.[NEW], tblWeather30DayMoving.[RptdDate], tblWeather30DayMoving.[Clm Nbr], 1 AS WeatherLimit " & _
"FROM tblWeather30DayMoving WHERE (((tblWeather30DayMoving.NEW)= strTerritory ) AND ((tblWeather30DayMoving.RptdDate) Between #mm/01/yyyy# And #mm/28/yyyy#)); "
Set rst = dbs.OpenRecordset("tblWeather30DayMoving", dbOpenTable)
With rst
For j = 2003 To 2013
For i = 1 To 12
If Not (rst.EOF And rst.BOF) Then
.MoveFirst
Do
sql2 = replace(1, sql,"yyyy", cstr(j)) 'replace "jjjj" by year
sql2 = replace(1,sql2,"mm", format(i,"00")) 'replace "mm" by month
debug.print sql2
CurrentDb.Execute sql2 'this can be REM'd once it is all working
.MoveNext
Loop Until .EOF
End If
Next i
Next j
End With
Set rst = Nothing
End Sub
Also note that you did not set Option Explicit, and you are mixing variable names between strSql and Sql.
I created the sql string using silly dates, and then replaced them by the appropriate figues in the loop, just before execution. Not the most efficient, but I find it easy and readable.