So I've recently been working on a VBA script to transfer an entire database of student medical records from their old one-table, 68-field, flat system to a new dynamic system with 24 related tables.
There was no issue for the first few tables, but then I ran into this. The line of code throwing the error is:
Set rstFrom = CurrentDb.OpenRecordset("select " & Flat & ".Student," & Flat & ".School," & Flat & ".Social," & Flat & ".FamilyHist from " & Flat & " WHERE 1=1")`
Flat is a String which stores the name of the flat database (this is because I'm working with a dummy database so they will need a convenient and quick way to modify the code I make to work on the real thing)
rstFrom needs to contain only the columns of the 68-field table which are relevant to the table that I'm copying to at the moment (in this case, the FamilyHistory table which really just needs the studentID and FamilyHistory) - note that the original table did not assign unique studentIDs, so I must use the name, school, and social to determine that I am dealing with the same child and look up their studentID
When this line of code runs I get the following error:
Run-time error '3061':
Too few parameters. Expected 1.
Clearly I have 1 parameter, it's:
"select " & Flat & ".Student," & Flat & ".School," & Flat & ".Social," & Flat & ".FamilyHist from " & Flat & " WHERE 1=1"
(which after parsing is):
"select Demos.Student,Demos.School,Demos.Social,Demos.FamilyHist from Demos WHERE 1=1"
The where 1=1 is required when working with Access VBA or else it only returns the first record which matches, not all matching records.
Has anyone else had this same problem as resolved it? I did notice one thing. When I change the parameter to:
"select Demos.Student from Demos WHERE 1=1"
It is able to get past this line no problem, although this causes issues later on when I need to read other data that I did not retrieve. I thought it was interesting, though, that the error seems to be coming from the SQL and not the OpenRecordset function.
Check the field names in the SQL vs what you have in table.
I think, either the field name in above SQL is misspell or you don't have one or more field (of SQL statement) in the table.
The text parameters in the insert query need to have a single quote around them. I ran into the same problem with a query using Visual C++.
Here's the code I ended up using...
void FileInterface::TblWrite(CDatabase* db, rec* r)
{
string sqlQuery = "insert into THREATS(ID,CODE,ID,LAT,LON,SHOW_A,SHOW_B) Values(" +
to_string((_Longlong)r->num) + "," +
to_string((_Longlong)r->code) + "," +
"'" + r->id + "'" + "," +
to_string((long double)r->lat) + "," +
to_string((long double)r->lon) + "," +
"1" + "," +
"1" +
")";
db->ExecuteSQL(sqlQuery.c_str());
}
Related
I have a table in excel, with range : Sheets("Sheet1").Range("d4:d215"). These data are similar to PS.WELL in the server.
From that table, I want to retrieve data using this code (other SQL requisite has been loaded, this is the main code only):
strquery = "SELECT PS.WELL, PS.TYPE, PS.TOPSND " & _
"FROM ISYS.PS PS " & _
"WHERE PS.WELL = '" & Sheets("Sheet1").Range("D4:D215") "' AND (PS.TYPE = 'O' OR PS.TYPE = 'O_' OR PS.TYPE = 'GOW') " & _
"ORDER BY PS.WELL"
Unfortunately it didn't work. Can anyone help me how to write the code especially in the 'where' section?
You have to iterate through each item in the range and concatenate the results to a string variable so the contents look like this
'val1','val2','val3'
Then you have to adjust your query code to use the IN operator instead of equals operator. Let's say the string is concatenated to a variable called myrange.
"WHERE PS.WELL IN (" & myrange & ") AND ...
I have solved the problem. The key is to make 2 function of SQL:
to read and write each input
to count number of output per input (an input can have 0, 1, or more output).
then, just call using procedure
I am a data consultant who migrates data I am sent into our system. I have written code that compares the contents of my table against what has been put into oracle, as an extra test. The tables are a little convoluted due to how they relate to each other. But essentially here is my question:
When I look to match two field values and the field doesnt exist I get a parameter pop up box. I want to only run the code if the field exists.
I have tried many things, wrapping an if statement around it but I always get the parameter box, can anyone help there must be an easier way to do this!
If Not DoCmd.OpenQuery("SELECT TOP 1" & MatchValues!FieldName & " FROM " &
MatchValues!ORACLE_TABLE_NAME) Then
MsgBox "moomins"
' strSQL = "INSERT INTO 002_TableValueErrors(ORACLE_TABLE_NAME,TRANSFORM_TABLE_NAME,FIELD_NAME,ORACLE_FIELD_VALUE,TRANSFORM_FIELD_VALUE) "
' strSQL = strSQL & " VALUES (" & MatchValues!ORACLE_TABLE_NAME & "," & MatchValues!TRANSFORM_TABLE_NAME & "," & MatchValues!FieldName & ",'ORACLE: NOT FOUND','ORACLE: NOT FOUND')"
End If
If you deal with Oracle: Have you tried to check if the field exists by querying ALL_TAB_COLUMNS in Oracle?
"Select count(*) from ALL_TAB_COLUMNS where table_name = " & MatchValues!ORACLE_TABLE_NAME & " and COLUMN_NAME = " & MatchValues!FieldName
(Untestet cause currently I have no Oracle Instance available)
I have a table that stores a string representing a formula that I would like to have either Access or VBA evaluate. A few example strings look like:
table.FirstName & ' ' & table.LastName
table.LastName & ', ' & table.FirstName
table.LastName & ', ' & table.FirstName & ' ' & LEFT(table.Middle,1)
Basically, I'm trying to change how different names can be viewed based on entity type, missing information, etc.
Is there any way to force either Access (in a query) or VBA (as part of a custom function) to return what the string is telling it as opposed to the literal value? From the examples above, I would expect:
table.FirstName table.LastName
table.LastName, table.FirstName
table.LastName, table.Firstname, t
Replace by itself won't work, as some of the formatting includes LEFT(table.Name,1) or other functions. I'm just hoping there is a simple way to force the string to be evaluated, rather than having to come up with a complex function.
I apologize if I haven't explained this well, I feel like my attempt to merge the database aspect with the string formatting aspect may not come across clearly. If you have questions please reply and I'll do my best to explain it better.
Thank you in advance.
How about the Microsoft Access Eval() function:
?Eval("3 + 1")
4
You could build an SQL string from your table formulas like:
SQL = "Select " & tblFormulas.FormulaField.Value & " From " & Split(tblFormulas.FormulaField.Value, ".")(0) & ";"
Not bullet-proof but a start ...
As you have a special table with formulas you can aim at queries and/or VBA.
For VBA you can store code for eval function to be run in form of several forms with same set of required fields(that is used in formulas):
in field VBAformula of your special table should resides such string me![LastName] & ', ' & me!FirstName & ' ' & LEFT(Me![Middle],1)
then in some function you could write:
formula = dlookup("VBAformula","SpecialTable","id=" & me![HowToViewID])
Me![ViewAs] = eval(formula)
For Queries you can store SQL formula to be used in UPDATE query, SQLformula with such string:
[LastName] & ", " & [FirstName] & " " & LEFT([Middle],1) then you can build and run SQL:
formula = dlookup("SQLformula","SpecialTable","id=" & me![HowToViewID])
currentdb.Execute "UPDATE [table with people] SET [ViewAs] = " & formula & " WHERE peopleID=" & Me![peopleID] & ";" , dbFailOnError
These are examples to show some variants, so there is no error handling or security.
OK usually I'm pretty good at googling around and using debug.print to isolate and solve the problem but this one is escaping me.
The purpose of this code is to create a new record in a table, using a form in which a person has selected a team member's name from a dropdown and a project phase from a dropdown and then input a number of hours into a textbox, then clicked a button that says "Add". There are a few if/thens involved but I'm leaving out the irrelevant parts (the code produces the same error in all cases.)
All of the code takes place inside one public function. All variables are Dim.
First it runs some code to find the value of "MyPersonID". (Complicated and not relevant as that works just fine).
Then it runs some code to find the value of "MyProjectPhaseID" which looks like this:
MyProjectPhaseID = [Forms]![HourValidationsFromTeam]![InputProjectPhase]
This variable populates correctly (as per Debug.Print)
Then it creates the INSERT SQL statement and runs it:
strAppendHourRecordSQL = "INSERT INTO PersonCommitmentsHours ( PersonNameLookup, ProjectPhase, WeekOfCommitment, DateValidated, HourCommitment, ValidationResult ) SELECT '" & (MyPersonID) & "' AS PersonNameLookup, '" & MyProjectPhaseID & "' AS ProjectPhase, [Forms]![HourValidationsFromTeam]![LastWeekDate] AS Week, Date$() AS TodaysDate, [Forms]![HourValidationsFromTeam]![InputSuppliedHours] AS Hours, " & Chr(34) & "More" & Chr(34) & " AS ValidationType;"
Debug.Print MyProjectPhaseID
Debug.Print strAppendHourRecordSQL
DoCmd.RunSQL strAppendHourRecordSQL
This is what Debug.Print returns:
2069
INSERT INTO PersonCommitmentsHours ( PersonNameLookup, ProjectPhase, WeekOfCommitment, DateValidated, HourCommitment, ValidationResult ) SELECT '260' AS PersonNameLookup, '' AS ProjectPhase, [Forms]![HourValidationsFromTeam]![LastWeekDate] AS Week, Date$() AS TodaysDate, [Forms]![HourValidationsFromTeam]![InputSuppliedHours] AS Hours, "More" AS ValidationType;
The query runs correctly and inserts a record with everything in the right place except it's missing the value where MyProjectPhaseID should go. It's just null. I thought maybe the variable was null, but Debug.Print returns the correct value. Even the debugger fills the value in when I hover over the SQL.
I tried different combinations of adding and removing parentheses and quotes around the variable in the SQL but they have no effect.
Please help!
I figured out the problem. The problem is that you cannot define the SQL before the variables have been populated. I thought you could define the SQL and then re-use it depending on where you get your variables from. But no. That's why it had the right value for the variable, but it couldn't put them together. I didn't make it clear from the way I wrote the question that this could be a suspect, i'm sorry about that.
So in order to not try to pre-define SQL for variables that don't exist yet, I isolated the part of the SQL that won't change and define that first as strBoilerplateSQL.
Then do the IF statement for the stuff that could change, then define the part of the SQL statement that depends on that change, then concat the 2 sql statements together. Then it runs the completed SQL statement.
strBoilerplateSQL = "INSERT INTO PersonCommitmentsHours ( PersonNameLookup, WeekOfCommitment, DateValidated, HourCommitment, ValidationResult, ProjectPhaseLookup ) SELECT " & (MyPersonID) & " AS PersonNameLookup, [Forms]![HourValidationsFromTeam]![LastWeekDate] AS Week, Date$() AS TodaysDate, [Forms]![HourValidationsFromTeam]![InputSuppliedHours] AS Hours, " & Chr(34) & "More" & Chr(34) & " AS ValidationType, "
'Check to see if this is going in to an existing project or should we create a new project first
If (IsNull([Forms]![HourValidationsFromTeam]![InputNewProject].Value)) Then
'If the Input New Project text box is null, assemble the SQL and run it
MyProjectPhaseID = [Forms]![HourValidationsFromTeam]![InputProjectPhase].Value
strMyProjectPhaseSQL = "" & (MyProjectPhaseID) & " AS ProjectPhase;"
strReadySQL = (strBoilerplateSQL) & (strMyProjectPhaseSQL)
DoCmd.RunSQL strReadySQL
Else
'Some other stuff happens here
MyProjectPhaseID = GetPhaseID![TheProjectPhase]
'Now that we have the new project phase ID we can run the SQL from above (oh hey remember that?)
strMyProjectPhaseSQL = "" & (MyProjectPhaseID) & " AS ProjectPhaseLookup;"
strReadySQL = (strBoilerplateSQL) & (strMyProjectPhaseSQL)
DoCmd.RunSQL strReadySQL
End If
I am connecting to a Access DB, with following Conn String
Conn.Open "PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=\\server\share\Data\PFWTRAN.MDB"
The following SQL works fine;
SQLIn = "SELECT Date, Time " & _
"FROM Transactions " & _
"WHERE TokenNumber = " & TokenNo & " " & _
"AND Date >= " & FromDateG & " " & _
"AND Direction = -1 " & _
"ORDER BY Date, TransactionNumber;"
However, I want rows where Transactions.Exception = 0, yet when I add this AND condition, the script fails when the RS is opened;
error '80004005' /path/.../.../...asp, line 97
If I remove the AND condition, it works again.
Even If I try and put 'Exception' in the SELECT section, it won't run and gives me that error.
Why would the inclusion of one field cause such an error? I read the error is due to permissions, but my permissions are fine as the SQL works without this one field in it.
Any clues?
It is a very old Access 95 database (or even earlier), perhaps I need to change connection provided?
"However, I want rows where Transaction.Exception = 0, yet when I add this AND condition, the script fails when the RS is opened"
But Transaction.Exception refers to a different table than the one your query uses.
FROM Transactions
Date, Time, and Exception are Problem names and reserved words in Access. Enclose those names in square brackets, or prefix them with the table name/alias.
Consider switching your approach to use a parameter query ... and feed it TokenNo and FromDateG values as parameters, rather than building their values into the SELECT statement.