Not match the datatypes of the criteria expression ms access - vba

I have a update like this in a module of ms access:
sql = "ALTER TABLE Carrera "
sql = sql & "ADD COLUMN carrera_nombre TEXT(25);"
Application.CurrentDb.Execute (sql)
sql = "UPDATE Carrera "
sql = sql & "SET Carrera.[carrera_nombre] = '" & strFunction(Carrera.[NombreCarrera]) & "' "
sql = sql & "WHERE Carrera.[CarreraId] > 1000;"
Application.CurrentDb.Execute (sql)
In database the column NombreCarrera exist, and I declared the function:
Function strFunction(str) As String
strFunction = str & "test"
End Function
But I get the error 3464 Not match the datatypes of the criteria expression, and I don't understand why, the strFunction return a String and the carrera_nombre and CarreraNombre columns type is TEXT.
EDIT: If I check string sql through MsgBox(sql) y get the right query: UPDATE Carrera SET Carrera.[carrera_nombre] = 'mathtest' WHERE Carrera.[CarreraId] > 1000;

I believe since you declare the sql command as a string, you will have to get it first.
so one of your code
sql = sql & "SET Carrera.[carrera_nombre] = strFunction(Carrera.[NombreCarrera])"
Should become
sql = sql & "SET Carrera.[carrera_nombre] = " & strFunction(Carrera.[NombreCarrera]) & """

Related

Access 2003: count(*) produces syntax error

I am using ms-access and for some reason, the code here produces a Syntax error which I dont understand.
UPDATE Korrekturentlastung
SET Schueler = SELECT COUNT(*)
FROM Korrekturentlastung
WHERE
Korrekturentlastung_Kurs.Kuerzel = Korrekturentlastung.Kuerzel
AND Korrekturentlastung_Kurs.Klasse = Korrekturentlastung.Klasse
AND Korrekturentlastung_Kurs.Fach = Korrekturentlastung.Fach
AND Korrekturentlastung_Kurs.Kursart = Korrekturentlastung.Kursart
The error is:
Syntax error. in query expression 'SELECT COUNT(*)
FROM Korrekturentlastung'
Whilst #Gordon Linoff has correctly identified the syntax error in your query, if you were to run the query in MS Access, you'll likely receive the familiar response:
Operation must use an updateable query.
This arises as a result of a restriction of the JET database engined used by MS Access whereby no part of an update query can use aggregation. In your case, this arises as a result of the use of count(*).
One possible alternative is to use the DCount domain aggregate function, which is evaluated separately from the evaluation of the main query and therefore retains the "updateability" of the query.
update korrekturentlastung
set schueler =
dcount
(
"*",
"Korrekturentlastung",
"Kuerzel = " & Korrekturentlastung.Kuerzel & " and "
"Klasse = " & Korrekturentlastung.Klasse & " and "
"Fach = " & Korrekturentlastung.Fach & " and "
"Kursart = " & Korrekturentlastung.Kursart
)
Note that if your fields are text fields, you'll also need to surround the above values with single or double quotes, e.g.:
update korrekturentlastung
set schueler =
dcount
(
"*",
"Korrekturentlastung",
"Kuerzel = '" & Korrekturentlastung.Kuerzel & "' and "
"Klasse = '" & Korrekturentlastung.Klasse & "' and "
"Fach = '" & Korrekturentlastung.Fach & "' and "
"Kursart = '" & Korrekturentlastung.Kursart & "'"
)
Subqueries need their own parentheses:
UPDATE Korrekturentlastung
SET Schueler = (SELECT COUNT(*)
FROM Korrekturentlastung
WHERE Korrekturentlastung_Kurs.Kuerzel = Korrekturentlastung.Kuerzel
AND Korrekturentlastung_Kurs.Klasse = Korrekturentlastung.Klasse
AND Korrekturentlastung_Kurs.Fach = Korrekturentlastung.Fach
AND Korrekturentlastung_Kurs.Kursart = Korrekturentlastung.Kursart
);

VBA (access) set data type when creating a table

I have a small problem. I have a VBA macro that creates a table. It works. But Call set data type "short text" and a need a number for column FB_average, Cil_FB and Plneni_FB.
Does anyone please have a solution tip?
Call generuj_t_vystup("t_prod_work_time_fb.Skill,t_prod_work_time_fb.Skill_KM,t_prod_work_time_fb.Locality,t_prod_work_time_fb.Team,t_prod_work_time_fb.Spv_name,t_prod_work_time_fb.Agent_name,t_prod_work_time_fb.Agent_login,t_prod_work_time_fb.Rok,t_prod_work_time_fb.Kvartal,t_prod_work_time_fb.Měsíc,t_prod_work_time_fb.Tyden,t_prod_work_time_fb.Event_date", "t_vystup_fb_denni_agent")
Public Function generuj_t_vystup(hlavicka As String, vystupni_tabulka As String)
SQL = "Select "
SQL = SQL & hlavicka & ", "
SQL = SQL & "Nz(SUM([Feedback_summary])) AS FB_summary,"
SQL = SQL & " Nz(SUM([Feedback_count])) AS FB_count,"
SQL = SQL & " Nz(SUM([Feedback_summary])/SUM([Feedback_count])) AS FB_average,"
SQL = SQL & " Nz(SUM([Feedback_summary])/SUM([Feedback_count])) AS Cil_FB,"
SQL = SQL & " Nz(SUM([Feedback_summary])/SUM([Feedback_count])) AS Plneni_FB"
SQL = SQL & " INTO "
SQL = SQL & vystupni_tabulka
SQL = SQL & " FROM t_prod_work_time_fb "
SQL = SQL & " GROUP BY "
SQL = SQL & hlavicka
spustsql SQL
End Function
Sub spustsql(SQL As Variant)
On Error GoTo chyba
DoCmd.RunSQL SQL
Exit Sub
Thanks a lot.
Set a numeric value (0) to replace Null:
SQL = SQL & " Nz(SUM([Feedback_summary]), 0) AS FB_summary,"
SQL = SQL & " Nz(SUM([Feedback_count]), 0) AS FB_count,"
SQL = SQL & " Nz(SUM([Feedback_summary])/SUM([Feedback_count]), 0) AS FB_average,"
SQL = SQL & " Nz(SUM([Feedback_summary])/SUM([Feedback_count]), 0) AS Cil_FB,"
SQL = SQL & " Nz(SUM([Feedback_summary])/SUM([Feedback_count]), 0) AS Plneni_FB"

Mismatch datatype criteria expression, string field

I have a ms access database and when I try to update a column in a module I get the error "Mismatch datatype criteria expression", when I create the column the datatype was TEXT(25) and the value that I'm trying to assign is a String:
Dim str As String
str = "test"
sql = "UPDATE Table "
sql = sql & "SET Table.[column] ='" & str & "' "
sql = sql & "WHERE Table.[id] = 1;"
MsgBox(sql)
Application.CurrentDb.Execute(sql)
In the MsgBox the string of query appears to be right: "UPDATE Table SET Table.[Column]='test' WHERE Table.[id]=1;
Which is the error?, how to fix this?
If Table.id is a numeric column your where clause is okay, but if it is a text column it should read:
WHERE Table.id = '1'

Store a sql select statement, ran from VBA, in a numeric variable

I'm working on creating a dynamic pass-through query and in order to do so I first need to query my local db and get an ID.
This ID is what I will put into my pass-through query for my WHERE clause of the query.
My string:
getCorpID = "SELECT corpID " & _
"FROM dbo_corp " & _
"WHERE name = " & Forms.frmMain.Combo4.Value
I'm then trying to do something akin to:
CorpID (integer) = docmd.runsql (getCorpID)
I realize, however that docmd runsql doesn't work with select statements, or return a value even. What can I use to run my string
getCorpId
as sql and store the result (It will only be one result, every time.. one number) in my variable CorpID
Thank you.
Consider about using Recordset :
Dim dbs As DAO.Database
Dim rsSQL As DAO.Recordset
Dim getCorpID As String
Dim CorpID
Set dbs = CurrentDb
getCorpID = "SELECT corpID " & _
"FROM dbo_corp " & _
"WHERE name = " & Forms.frmMain.Combo4.Value
Set rsSQL = dbs.OpenRecordset(getCorpID , dbOpenSnapshot)
rsSQL.MoveFirst
CorpID = rsSQL.Fields("corpID")

If/Then in SQL Embedded in VBA

I've got a string like this in my Excel VBA:
strSQL = "SELECT * FROM Total WHERE (SimulationID = (" & TextBox1.Text & ") And Test1 = (" & Example & "))"
However, sometimes Test will be 'is null', which makes the query
And Example = is NULL
How can I change it to add an if/then statement or something to make it say
And Example is null
when Example has a value of "is null"?
I would suggest doing the NULL comparison before assembling the SQL statement strSQL.
If you check for the value of Example beforehand, you can alter your strSQL statement accordingly based on that check.
EDIT:
In response to Daniel's first and second comment below, I still would prefer the following over doing it inline:
Dim strSqlTail
strSqlTail = ""
If (Example1 = Null) Then strSqlTail = "AND Example1 IS NULL"
If (Example2 = Null) Then strSqlTail = strSqlTail & "AND Example2 IS NULL"
If (Example3 = Null) Then strSqlTail = strSqlTail & "AND Example3 IS NULL"
...
Note: The strSqlTail can be whatever SQL would make your situation work since I don't quite understand what is being queried from the sample.
You just create a function that puts the equal sign and space before the number if it doesn't equal "is null", and modify the string assignment statement appropriately, like so:
Public Function NullModString(Example As String) As String
If Example <> "is null" Then Example = "= " & Example
NullModString = Example
End Function
strSQL = "SELECT * FROM Total WHERE SimulationID = " & TextBox1.Text & _
"And Test1 " & NullModString(Example)
Note, that I didn't understand why the extra parentheses were in there, but it would be simple to put them back in.
One solution is to coalesce out the null using a Coalesce function (or if using Access, the Nz function) :
trSQL = "SELECT ..." & _
" FROM Total" & _
" WHERE SimulationID = " & TextBox1.Text & " & _
" And Coalesce(Test1,"""") = "" & Example & """
A better way would be to dynamically include or not include the entire And statement based on whether Example had a value or to substitute Test Is Null when Example did not have a value. So something akin to:
Dim testElements() As Variant
Dim vElement As Variant
Redim testElements(6,1)
testElements(0,0) = Example1
testElements(0,1) = "Test1"
testElements(1,0) = Example2
testElements(1,1) = "Test2"
...
Dim elementIndex as Integer
Dim colName As String
Dim elementValue As Variant
For elementIndex = 0 To UBound(testElements)
elementValue = testElement(elementIndex, 0)
colName = testElement(elementIndex, 1)
If Len(Nz(elementValue)) = 0 Then
trSQL = trSQL & " And " & colName & " = """ & Example1 & """
Else
trSQL = trSQL & " And " & colName & " Is Null"
End If
Next
First, don't embed SQL in VBA: hard to maintain, SQL injection, etc. Use a stored proc on the database side (even Access has PROCEDUREs).
Second, use COALESCE (or equivalent logic) to handle your 'empty string equates to NULL' UI logic. You don't say which SQL syntax and you haven't posted schema DLL so we're merely guessing...
SQL Server:
CREATE PROCEDURE GetTotals
#SimulationID INTEGER,
#Test1 VARCHAR(20) = NULL
AS
SELECT *
FROM Total AS T1.
WHERE T1.SimulationID = #SimulationID
AND COALESCE(T1.Test1, '') = COALESCE(#Test1, '');
Access Database Engine (a.k.a. Jet):
CREATE PROCEDURE GetTotals
(
:SimulationID INTEGER,
:Test1 VARCHAR(20) = NULL
)
AS
SELECT *
FROM Total AS T1
WHERE T1.SimulationID = :SimulationID
AND IIF(T1.Test1 IS NULL, '', T1.Test1)
= IIF(:Test1 IS NULL, '', :Test1);
Then execute the proc using your middleware (ADO, DAO, etc) with Parameter objects, using the empty string (or other 'magic' value) for NULL.