I'm working in an MS Access Database, and have the following query:
DoCmd.RunSQL "INSERT INTO My_Table_Temp (Value1, Value2, IsDirty, HWND)" _
& " SELECT Value1, Value2, 0 as IsDirty, " & sqe(Me.HWND) & " as HWND" _
& " FROM My_Table; "
The idea is that I load values from the database into a temporary table, which I can then bind to a control, so I can add and remove values from it, before writing the values back into the database.
My problem is that HWND never gets set, so that when I filter by it to save the records, nothing gets picked up. The values already in the database show up, it's just the HWND that never gets set. Am I missing something completely obvious?
I created a msaccess MDB, and then created a "hr_training_levels_temp" table.
I do not have the "FROM" table,
so I hard-coded some values (and changed values suffixing with '2')... as in this sql --
INSERT INTO hr_training_levels_temp
(traininglevel,
trainingleveldesc,
traininglevelid,
trainingid,
isdirty,
hwnd)
SELECT 'lvla',
'lvla-desc',
'lvla-id',
'tr-id',
0 AS IsDirty,
'920902' AS HWND
And in msaccess, when I double-click on the table I got this result --
traininglevel trainingleveldesc traininglevelid trainingid isdirty HWND
lvla lvla-desc lvla-id tr-id 0 920902
lvla2 lvla2-desc lvla2-id tr-id2 0 920903
Do you see such a result in the msaccess table itself?
Then when your display screen comes back and does a select using HWND, is it the same HWND that was used to do the Insert?
Related
Any help that can be provided to a Access and VB noob would be greatly appreciated. What I'm trying to do is concatenate the values from one table and insert it as a comma delimited value into a field in another table. I'm trying to take all the server names that are say Linux boxes and concatenate them into a different field.
Table A looks like this
Machine Name | Zone | Operating System
----------------------------------------
Server01 Zone A Linux
Server02 Zone B Linux
Server03 Zone A Windows
Server04 Zone C Windows
Server05 Zone B Solaris
Table B has the field I want to insert into: Affected_Machine_Names.
Now, I've tried looking through the Concatenate/Coalesce posts, but the SQL view in Access doesn't like the Declare statements. My VB skills suck badly and I can't seem to get the code to work in VB for Applications. Unfortunately, I can't get this database converted into our SQL farm cause I don't have a server available at the moment to host it.
Can anyone point me in the right direction?
You can use Concatenate values from related records by Allen Browne for this. Copy the function code from that web page and paste it into a new standard module. Save the module and give the module a name different from the function name; modConcatRelated would work.
Then I think you should be able to use the function in a query even though you're not proficient with VBA.
First notice I changed the field names in TableA to replace spaces with underscores. With that change, this query ...
SELECT
sub.Operating_System,
ConcatRelated("Machine_Name", "TableA",
"Operating_System = '" & sub.Operating_System & "'") AS Machines
FROM [SELECT DISTINCT Operating_System FROM TableA]. AS sub;
... produces this result set:
Operating_System Machines
Linux Server01, Server02
Solaris Server05
Windows Server03, Server04
If you can't rename the fields as I did, use a separate query to select the distinct operating systems.
SELECT DISTINCT TableA.[Operating System]
FROM TableA;
Save that as qryDistinctOperatingSystems, then use it in this version of the main query:
SELECT
sub.[Operating System],
ConcatRelated("[Machine Name]", "TableA",
"[Operating System] = '" & sub.[Operating System] & "'") AS Machines
FROM qryDistinctOperatingSystems AS sub;
This is a fairly basic VBA function that will loop through every row in a column, and concatenate it to a comma-delimited result string. i.e., for your example, it will return "Server01, Server02, Server03, Server04, Server05". (Don't forget to replace the column and table names)
Function ConcatColumn(OS As String) As String
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("Select * from TableA")
Dim result As String
'For every row after the first, add a comma and the field value:
While rst.EOF = False
If rst.Fields("Operating System") = OS Then _
result = result & ", " & rst.Fields("MyValue")
rst.MoveNext
Wend
'Clean it up a little and put out the result
If Left(result, 2) = ", " Then result = Right(result, Len(result) - 2)
Debug.Print result
ConcatColumn = result
End Function
To use this,
1. ConcatColumn("Windows") will return "Server04, Server03"
2. ConcatColumn("Linux") will return "Server01, Server02"
3. ConcatColumn("Solaris") will return "Server05"
4. ConcatColumn("") will return "".
I'm using an access function that loops through multiple record sets using case select statements and displays rows of strings in the VBA immediate window.
Can anyone suggest how I can learn about methods that might be used to update a table with the results that are currently displayed in the VBA immediate window?
So far, my searches have suggested that DoCmd.SQL might work.
Case Is = "1" ' 1 bottle
Debug.Print rsWCol!r4_wcol_outstring & rsBottl!bottleoutstring
displays the string below in the immediate window:
R41602T50 1 00 62 710 C 1120 9800 550 1 00S #135 0
I'd like to be able to use something like the following
Dim writeRecSQL As String ' used to append records to a temp table
writeRecSQL = "INSERT INTO tbl_R_export_TEMP ( R_str ) select rsWCol!r4_wcol_outstring & rsBottl!bottleoutstring;"
Case Is = "1" ' 1 bottle
' Debug.Print rsWCol!r4_wcol_outstring & rsBottl!bottleoutstring
DoCmd.RunSQL writeRecSQL
The select part of my SQL statement does not seem to be getting values.
I understand that, normally, it might be something like select fieldX from tablex
And that my statement is more like: select rs!foo
An 'Enter Parameter Value' message box is raised asking for the value of r4_wcol_outstring
(Following the SELECT in my SQL with a FROM raises VB "Run-time error '3134' syntax error in INSERT INTO statement.")
I could use some advice or an example of how write an SQL statement that will my record set parameter values.
Good place to start is Microsoft's site:
https://msdn.microsoft.com/en-us/library/bb208861(v=office.12).aspx
But if you just want to insert values from a record you just retrieved into another table
try wrapping fields in escaped double quotes and concetanting the values outside the hardcoded string.
As in:
writeRecSQL = "INSERT INTO tbl_R_export_TEMP ( [R_str] ) VALUES (""" & rsWCol!r4_wcol_outstring & rsBottl!bottleoutstring & """);"
Besides Docmd.RunSQL, you can also look at CurrentDB.Execute and predefined parameter queries using the Querydefs object
I have an Access DB, it's a local development copy, not production, and corrupted during (ironically) compact and repair, a large amount of data. Unfortunately I did a lot of work on it and I do have a backup plan but it failed me..
When I start it up it gives me useless error messages like:
'Id' is not an index in this table.
'ParentIdName' is not an index in this table.
I suppose these indexes are part of the hidden MSys* tables in the DB. I managed to read those and they're mostly empty while my older healthy backup has a lot of data in these tables.
First I tried to restore the healthy tables into the destroyed ones using VBA and an ADO connection (made a copy beforehand), I get a lot of errors saying I don't have write permissions on the tables.
Next attempt, still ongoing, is to recover the query definitions (90%+ of my changes) through the same ADO connection (tried ADOX and DAO too).
The most successful attempt was ADO:
Sub DebugPrintQueryDefsADO()
Dim dmgDB As DAO.Database
Dim dmgQD As DAO.QueryDef
Set dmgDB = DBEngine.OpenDatabase("C:\Database.accdb", , True)
For Each dmgQD In dmgDB.QueryDefs
If Left(dmgQD.Name, 1) <> "~" Then ' ~ Query defs seem to be the form views'
Debug.Print "---------------------------------"
Debug.Print dmgQD.Name
Debug.Print "---------------------------------"
Debug.Print dmgQD.SQL
End If
Next dmgQD
Set dmgQD = Nothing
Set dmgDB = Nothing
End Sub
This actually works! As long as the Query definition evaluation runs fine first. Which in my case cannot be true for most QD's since the tables are imported when required and then deleted. This means that the fields defined in the QD's cannot be found because the tables aren't there. Then Access presents me an error:
3258: The SQL Statement could not be executed because it contains ambiguous outer joins. To force one of the joins to be performed first, create a separate query that performs the first join and then include that query in your SQL statement.
Go home Access, you're drunk.
Next quest was to figure out how to not evaluate the SQL statement (I only need the SQL statement, not the result). I found that there is a property: Querydef.Prepare in this Access 2007 doc: http://msdn.microsoft.com/en-us/library/office/bb208511(v=office.12).aspx
According to the documentation (of Access 2007, I have 2010), I should set
Querydef.Prepare = dbQUnprepare. But that does not work..
So long problem short..
Is anyone aware of a way to fix the corrupted DB?
OR..
Does anyone know how to retrieve my SQL statements from the query definitions without the need to evaluate them?
Thanks!
One option you could try would be
Application.SaveAsText acQuery, "QueryName", "C:\path\QueryName.txt"
At least in some cases it dumps the SQL string at the beginning of the file (with some arbitrary breaks and escaped characters, just to keep things interesting). For example:
dbMemo "SQL" ="SELECT YEAR(Assigned.[Date]) AS Yr, MONTH(Assigned.[Date]) AS Mo, SUM(Assigned.["
"Hours Worked]) AS Hrs\015\012FROM Assigned INNER JOIN Projects ON Projects.[Proj"
"ect Name] = Assigned.[Project Name]\015\012WHERE Projects.Billable\015\012GROUP "
"BY YEAR(Assigned.[Date]), MONTH(Assigned.[Date]);\015\012"
dbMemo "Connect" =""
dbBoolean "ReturnsRecords" ="-1"
dbInteger "ODBCTimeout" ="60"
dbBoolean "OrderByOn" ="0"
dbByte "Orientation" ="0"
dbByte "DefaultView" ="2"
dbBinary "GUID" = Begin
0x1304ebdf78bef2459211d478954077cd
End
dbBoolean "FilterOnLoad" ="0"
dbBoolean "OrderByOnLoad" ="-1"
dbLongBinary "DOL" = Begin
0x0acc0e5500000000534cc617867b4d43b98002a1b002c8eb00000000c732603a ,
0xa958e4400000000000000000410073007300690067006e006500640000000000 ,
0x00006b84dfe37aec2248a1ccfe3e157361df0000000040b3affda358e4400000 ,
0x000000000000500072006f006a006500630074007300000000000000d5b092f5 ,
0x1c13394884636d668e066e66070000001304ebdf78bef2459211d478954077cd ,
0x59007200000000000000efa363bc29cbfc478a958e7b935d03da070000001304 ,
0xebdf78bef2459211d478954077cd4d006f00000000000000b1174c1abe1d3d4c ,
0xb9a1a7e5915a2e47070000001304ebdf78bef2459211d478954077cd48007200 ,
0x7300000000000000b2e4aa9aab3a9e479c47b2772754fce107000000534cc617 ,
0x867b4d43b98002a1b002c8eb4400610074006500000000000000404c3a80ef29 ,
0xa4498e153e354319e84c07000000534cc617867b4d43b98002a1b002c8eb4800 ,
0x6f00750072007300200057006f0072006b0065006400000000000000a3a95acb ,
0xe7ec994bab8df870ce5b3d98070000006b84dfe37aec2248a1ccfe3e157361df ,
0x500072006f006a0065006300740020004e0061006d006500000000000000f5cb ,
0xefb11bcf5e4da4b2806eed09a70207000000534cc617867b4d43b98002a1b002 ,
0xc8eb500072006f006a0065006300740020004e0061006d006500000000000000 ,
0x453445bf7e67b54ead2c9317ca29d906070000006b84dfe37aec2248a1ccfe3e ,
0x157361df420069006c006c00610062006c006500000000000000000000000000 ,
0x000000000000000000000c000000050000000000000000000000000000000000
End
dbByte "PublishToWeb" ="1"
Begin
Begin
dbText "Name" ="Yr"
dbLong "AggregateType" ="-1"
dbBinary "GUID" = Begin
0xd5b092f51c13394884636d668e066e66
End
End
Begin
dbText "Name" ="Mo"
dbLong "AggregateType" ="-1"
dbBinary "GUID" = Begin
0xefa363bc29cbfc478a958e7b935d03da
End
End
Begin
dbText "Name" ="Hrs"
dbLong "AggregateType" ="-1"
dbBinary "GUID" = Begin
0xb1174c1abe1d3d4cb9a1a7e5915a2e47
End
End
End
You can use Access Fix from AccessFix.com, if you have a copy of the database, which just got corrupted, and you didn't try anything on it that may have changed the data. Like, if you tried to compact and repair, your objects are gone after that. I use it at work and it fixes dbs for me in most cases. I would also try http://allenbrowne.com/tips.html, can't quite remember, but he had a set of steps there that you can use to recover the entire database from text. I think he explained it in his tips and tricks book, with Dough Steele, also
Any help that can be provided to a Access and VB noob would be greatly appreciated. What I'm trying to do is concatenate the values from one table and insert it as a comma delimited value into a field in another table. I'm trying to take all the server names that are say Linux boxes and concatenate them into a different field.
Table A looks like this
Machine Name | Zone | Operating System
----------------------------------------
Server01 Zone A Linux
Server02 Zone B Linux
Server03 Zone A Windows
Server04 Zone C Windows
Server05 Zone B Solaris
Table B has the field I want to insert into: Affected_Machine_Names.
Now, I've tried looking through the Concatenate/Coalesce posts, but the SQL view in Access doesn't like the Declare statements. My VB skills suck badly and I can't seem to get the code to work in VB for Applications. Unfortunately, I can't get this database converted into our SQL farm cause I don't have a server available at the moment to host it.
Can anyone point me in the right direction?
You can use Concatenate values from related records by Allen Browne for this. Copy the function code from that web page and paste it into a new standard module. Save the module and give the module a name different from the function name; modConcatRelated would work.
Then I think you should be able to use the function in a query even though you're not proficient with VBA.
First notice I changed the field names in TableA to replace spaces with underscores. With that change, this query ...
SELECT
sub.Operating_System,
ConcatRelated("Machine_Name", "TableA",
"Operating_System = '" & sub.Operating_System & "'") AS Machines
FROM [SELECT DISTINCT Operating_System FROM TableA]. AS sub;
... produces this result set:
Operating_System Machines
Linux Server01, Server02
Solaris Server05
Windows Server03, Server04
If you can't rename the fields as I did, use a separate query to select the distinct operating systems.
SELECT DISTINCT TableA.[Operating System]
FROM TableA;
Save that as qryDistinctOperatingSystems, then use it in this version of the main query:
SELECT
sub.[Operating System],
ConcatRelated("[Machine Name]", "TableA",
"[Operating System] = '" & sub.[Operating System] & "'") AS Machines
FROM qryDistinctOperatingSystems AS sub;
This is a fairly basic VBA function that will loop through every row in a column, and concatenate it to a comma-delimited result string. i.e., for your example, it will return "Server01, Server02, Server03, Server04, Server05". (Don't forget to replace the column and table names)
Function ConcatColumn(OS As String) As String
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("Select * from TableA")
Dim result As String
'For every row after the first, add a comma and the field value:
While rst.EOF = False
If rst.Fields("Operating System") = OS Then _
result = result & ", " & rst.Fields("MyValue")
rst.MoveNext
Wend
'Clean it up a little and put out the result
If Left(result, 2) = ", " Then result = Right(result, Len(result) - 2)
Debug.Print result
ConcatColumn = result
End Function
To use this,
1. ConcatColumn("Windows") will return "Server04, Server03"
2. ConcatColumn("Linux") will return "Server01, Server02"
3. ConcatColumn("Solaris") will return "Server05"
4. ConcatColumn("") will return "".
I have the following 'set recordset' line that I cannot get working. The parameters seem correct according to all available help I can find on the subject.
The error displays :
"Run-time error '3061'. Too few parameters. Expected 1."
Here is the line of code:
Set rs = dbs.OpenRecordset("SELECT Centre_X, Centre_Y FROM [qry_all_details]
WHERE ID = " & siteID & ";", dbOpenSnapshot)
Where rs is the recordset (Dim rs As Recordset) and dbs = CurrentDb()
Any help would be appreciated.
I have tried removing the WHERE cause with no effect, and also using single quotes between double quotes, but no joy.
Many thanks.
"Run-time error '3061'. Too few parameters. Expected 1."
I believe this happens when the field name(s) in your sql query do not match the table field name(s), i.e. a field name in the query is wrong or perhaps the table is missing the field altogether.
you have:
WHERE ID = " & siteID & ";", dbOpenSnapshot)
you need:
WHERE ID = "'" & siteID & "';", dbOpenSnapshot)
Note the extra quotations ('). . . this kills me everytime
Edit: added missing double quote
(For those who read all answers). My case was simply the fact that I created a SQL expression using the format Forms!Table!Control. That format is Ok within a query, but DAO doesn't recognize it. I'm surprised that nobody commented this.
This doesn't work:
Dim rs As DAO.Recordset, strSQL As String
strSQL = "SELECT * FROM Table1 WHERE Name = Forms!Table!Control;"
Set rs = CurrentDb.OpenRecordset(strSQL)
This is Ok:
Dim rs As DAO.Recordset, strSQL, val As String
val = Forms!Table!Control
strSQL = "SELECT * FROM Table1 WHERE Name = '" & val & "';"
Set rs = CurrentDb.OpenRecordset(strSQL)
My problem was also solved by the Single Quotes around the variable name
I got the same error message before.
in my case, it was caused by type casting.
check if siteID is a string, if it is you must add simple quotes.
hope it will help you.
My problem turned out to be, I had altered a table to add a column called Char.
As this is a reserved word in MS Access it needed square brakcets (Single or double quote are no good) in order for the alter statement to work before I could then update the newly created column.
Make sure [qry_all_details] exists and is runnable. I suspect it or any query it uses, is missing the parameter.
I got the same error with something like:
Set rs = dbs.OpenRecordset _
( _
"SELECT Field1, Field2, FieldN " _
& "FROM Query1 " _
& "WHERE Query2.Field1 = """ & Value1 & """;" _
, dbOpenSnapshot _
)
I fixed the error by replacing "Query1" with "Query2"
In my case, I got this error when I tried to use in a query a new column, which I added to MySQL table (linked to MS Access), but didn't refresh it inside MS Access.
To refresh a linked remote table:
Open "Linked Table Manager" ("External Data" tab on ribbon);
Select a checkbox near the table you want to refresh;
Press "OK" button.
In my case I was receiving this error when running a query from VBA with this command:
CurrentDb.Execute "qryName"
Double clicking on the query to execute it, worked fine, no error.
Changing the code to the following also worked fine, no error.
DoCmd.OpenQuery "qryName"
Hope this helps someone else who is unexpectedly getting this error.
If someone could explain why the first command caused the error I'd love to know.
Does the query has more than the parameter siteID, becouse if you want to run the query one parameter still isn't filled witch gives you the error
In my case, I had simply changed the way I created a table and inadvertently changed the field name I tried to query. Make sure the field names you reference in the query actually exist in the table/query you are querying.
This Message is also possible to pop up, if there is a typo in the fields on which you define a join
Thanks for John Doe's solution that helped a lot. Mine is very similar with some difference, using TempVars
Instead of :
strSQL = "SELECT * FROM Table1 WHERE Name = Forms!Table!Control;"
I used:
strSQL = "SELECT * FROM Query1" , Query1 being common for other usage
Query1 as:
"Select Field1, Field2 from Table1 where Id= [TempVars]![MyVar]
And similarly, removing [TempVars]![MyVar] from view solved the problem.
In My case I had an INSERT INTO TableA (_ ,_ ,_) SELECT _ ,_ ,_ from TableB, a run-time error of 33061 was a field error. As #david mentioned. Either it was a field error: what I wrote in SQL statement as a column name did not match the column names in the actual access tables, for TableA or TableB.
I also have an error like #DATS but it was a run-time error 3464.