Troubles with joining tables in Excel VBA - sql

I'm trying to take a crystal report sql and convert it so I can use it in excel. I'm having troubles with the syntax of the joining statements in Excel. I can do a couple of tables individually, but cant combine them.
From crystal reports: What I'm trying to copy:
SELECT "Material_Req"."Job", "Material_Req"."Pick_Buy_Indicator", "Material_Req"."Material", "Material_Req"."Description", "Material_Req"."Vendor_Reference", "PO_Detail"."PO", "Material_Req"."Est_Qty", "Source"."Act_Qty", "PO_Header"."Vendor", "PO_Detail"."Due_Date"
FROM (("PRODUCTION"."dbo"."Material_Req" "Material_Req" LEFT OUTER JOIN "PRODUCTION"."dbo"."Source" "Source" ON "Material_Req"."Material_Req"="Source"."Material_Req") LEFT OUTER JOIN "PRODUCTION"."dbo"."PO_Detail" "PO_Detail" ON "Source"."PO_Detail"="PO_Detail"."PO_Detail") LEFT OUTER JOIN "PRODUCTION"."dbo"."PO_Header" "PO_Header" ON "PO_Detail"."PO"="PO_Header"."PO"
WHERE "Material_Req"."Pick_Buy_Indicator"='b' AND "Material_Req"."Est_Qty">"Source"."Act_Qty"
ORDER BY "Material_Req"."Job"
Previous one that worked:
sqlMatlReq = "select job.job, material_req.vendor_reference, material_req.Material,'' As Description, material_req.Vendor," _
& "(material_req.est_qty) As Qty, (material_req.act_qty) As Qty, " _
& "material_req.due_date, " _
& " material_req.status " _
& "from (material_req inner join job on material_req.job=job.job) " _
& "left join material on material_req.material=material.material " _
& "where material.material is not null " _
& "and job.part_number is not null " _
& "and Job.Status in('Active') " _
& "and material_req.act_qty in('0') " _
& "Union all " _
& "select job.job, material_req.vendor_reference, material_req.Material, material_req.description, material_req.Vendor," _
& "(material_req.est_qty), (material_req.act_qty) As Qty," _
& " material_req.due_date, material_req.status " _
& "from (material_req inner join job on material_req.job=job.job) " _
& "left join material on material_req.material=material.material " _
& "where material.material is null " _
& "and job.part_number is not null " _
& "and Job.Status in('Active') " _
& "and material_req.act_qty in('0') " _
& "order by job.job;"
As far as I got: having troubles combining the three
'sqlMatlReq = "select job.job, material_req.material, material_req.Vendor_Reference, material_req.description, material_req.Est_Qty " _
'& "from (material_req inner join job on material_req.job=job.job) " _
'sqlMatlReq = "select source.Act_Qty, PO_Detail.PO, PO_Detail.Due_Date " _
'& "from source left outer join PO_Detail on source.Act_qty=PO_Detail.PO_Detail "
'sqlMatlReq = "select PO_Header.vendor " _
'& "from PO_Header"
Thanks in advance.

SQL Server Stored Procedures for Use With Crystal Reports
CREATE PROCEDURE sp_SampleProcedure
AS
BEGIN
SET NOCOUNT ON;
SELECT table_catalog, table_schema, table_name, table_type
FROM tbldm.information_schema.tables
WHERE table_schema = 'dbo'
AND table_type = 'BASE TABLE';
END;
Where any query you would like to see supplying data to the Crystal Reports client should be represented by the last SELECT statement issued in the SQL Server STORED procedure. This example points to the SQL data dictionary of Table Names and Types.
Define a DSN connection between the Crystal Reports client and the SQL Database Server. There may already be one of other reports were designed before this.
Stored procedures should show up in its schema catalog alongside the other objects typically found by the Crystal report writer when selecting db objects to use.
Note, procedures can be parametrized and their input variables used throughout the procedure itself.

Related

Finding/Marking Duplicate Values using SQL

I am trying to update a column in my table to specify if the record is a duplicate or not. To do this I added a field called 'DuplicateRecord'.
I can't use the query wizard in access as the duplicate option in this only allows for 10 fields to be checked as a duplicate and my table has more than 10 fields.
The below code works for me:
Call Module1.RunSQL("UPDATE myTable " & _
"SET myTable.DuplicateRecord = TRUE " & _
"WHERE myTable.[CompanyID] IN (" & _
"SELECT * FROM " & _
"(SELECT myTable.[CompanyID] " & _
"FROM myTable " & _
"GROUP BY myTable.[CompanyID] " & _
"HAVING COUNT(*) > 1 ) T1 ) ")
However this code just runs off one field and I need it to run off all fields in the table (there are about 15 fields).
As a test I tried using two fields to see if I could get this working using the following:
Call Module1.RunSQL("UPDATE myTable " & _
"SET myTable.DuplicateRecord = TRUE " & _
"WHERE myTable.[CompanyID] AND myTable.[Product] IN (" & _
"SELECT * FROM " & _
"(SELECT myTable.[CompanyID], myTable.[Product], COUNT(*) " & _
"FROM myTable " & _
"GROUP BY myTable.[CompanyID], myTable.[Product] " & _
"HAVING COUNT(*) > 1 ) T1 ) ")
However I get an error message saying "Run-time error '3306' You have written a subquery that can return more than one field without using the EXISTS reserved word in the main query's FROM clause. Revise the SELECT statement of the subquery to request only one field."
I've tried googling the error but I can't seem to solve it as I don't fully understand it.
Does anyone know how I can apply the logic of testing for duplicates? Is there an easier way to do this then how I am currently trying? I will need to do this for the full record (15 fields), so I am a bit conscious that the way I am currently attempting this might not be the best fit.

Access VBA 'Syntax Error in Join Operation'

I'm trying to attach a SELECT query to a VBA object in Access, but I keep getting the error:
Syntax Error in Join operation
Dim sql As String
sql = "SELECT R_History.iteration, R.RuntimeID, Policylanguage.FormBody " & _
"FROM PolicyLanguage " & _
"INNER JOIN ([Policy&Elements] " & _
"INNER JOIN ((R " & _
"INNER JOIN R_History " & _
"ON (R.RunTimeID = R_History.RunTimeID " & _
"AND (R.ReportID = R_History.ReportID)) " & _
"INNER JOIN StatePolicyLanguage " & _
"ON R_History.Iteration = StatePolicyLanguage.Iteration) " & _
"ON [Policy&Elements].[Text&ElementID] = StatePolicyLanguage.[TextID&ElementID] " & _
"ON PolicyLanguage.TextID = [Policy&Elements].TextID " & _
"WHERE (((R.RuntimeID) = Dlast('runtimeID','r')));"
DoCmd.RunSQL (sql)
I can't get this to run for the absolute life of me. Can anyone tell what's wrong?
Edit: Here is the code I am trying to emulate
If you're running a query where the criteria are values entered in a form (e.g. field1 = frm1.txtValue), you could create a parameterized query where the passed parameters are added to the WHERE clause. That way, you don't have create SQL in VBA---you'd just have to set the parameters in VBA.
As noted by others, Access requires you to put parentheses after each join:
from (((Table1
inner join Table2 on Table2.field1 = Table1.field1)
inner join Table3 on Table3.field2 = Table2.field2)
inner join Table4 on Table4.field3 = Table3.field3)
So, as suggested by others, if you absolutely need to construct the query via VBA, keep your JOIN and ON clauses together to prevent confusion, and add the necessary parentheses.
I've found when you have to create complex queries in Access (either in the SQL editor or in VBA), it can be helpful to write the SQL in a more friendly editor (e.g. Notepad++) that supports things like syntax highlighting. Then, you can paste the query where it needs to go.

SQL query works slower than the Access query wizard

I am working on automation of elimination of unmatched rows in two tables in MS Access. As known, Access has a query wizard for this process which named Find unmatched records. This method works fast even for 500k data rows.
But when I execute a query in MS Access VBA it works so slowly. Is there a faster SQL implementation to eliminate data, or does MS Access use a different method? How can I make it fast?
Below is my query in VBA. Table1 and Table2 each have more than 100k rows.
strQuery = SELECT gsmno INTO newtablename FROM table1 WHERE gsmno NOT IN (SELECT gsmno FROM table2)
CurrentDb.Execute strQuery
Use a LEFT OUTER JOIN and check for NULL on the Table2 gsmno. Those are your Non-Matches.
strQuery = & _
"SELECT " & _
" t1.gsmno " & _
"INTO " & _
" newtablename " & _
"FROM " & _
" table1 as t1 " & _
"LEFT OUTER JOIN " & _
" table2 as t2 on " & _
" t1.gsmno = t2.gsmno " & _
"WHERE " & _
" isnull(t2.gsmno) = true;"
CurrentDb.Execute strQuery

ACCESS VBA using using one more SQL QUERY in WHERE clause

I have two tables, one is std Table and KeyTable.
I have to display the values of std table based on the condition of keytable.
For example, if the user selects ASIA, i have to create a sql query list of countries in ASIA and use this country values (example: INDIA,SRILANKA,BANGLADESH) as where clause in final query. I have tried building them. But I am not sure of the syntax
First query to filter out the values of ASIA
strSQL1 = "SELECT keytable.[Lead Country] FROM keytable WHERE keytable.country='" & lstcountry & "';"
Second query to display the values according to the first query in where clause
strSQL = "SELECT * FROM [Std Table] WHERE ([Std Table].Country IN (______));
The blank which i am missing.
You could just combine the two queries into one statement:
strSQL= "SELECT * " & _
"FROM [Std Table] " & _
"WHERE [Std Table].Country IN " & _
"(" & _
" SELECT s.[Lead Country] " & _
" FROM keytable AS s WHERE s.country = '" & lstcountry & "' " & _
")"
I'd try
strSQL1 = "SELECT keytable.[Lead Country] FROM keytable WHERE keytable.country='" & lstcountry & "'"
strSQL = "SELECT * FROM [Std Table] WHERE ([Std Table].Country IN (" & strSQL1 & "));"
SQL Server would allow you to do that, I guess that ACCESS supports this, too.
Please note that I removed the ; in strSQL1!
You could also provide a list of comma separated values:
strSQL = "SELECT * FROM [Std Table] WHERE ([Std Table].Country IN ('DE','UK','JP'));"

Operator/Syntax Error

I am executing SQL in VB6 and this is the string that I am using, where I define currFA as a number 1. I've been debugging and working at this since it's using inner joins and unions (it's a query I made in Access that I am trying to put into VB6 to run). Right now, I'm getting an operator missing error on the run.
sql = "SELECT DISTINCT [~ALLCBLEQ].Equipment, [~FIRE_AREAS].INDEX" _
& "FROM ([~FIRE_AREAS] INNER JOIN [~ALLTARGETS] ON [~FIRE_AREAS].FULL_ID = [~ALLTARGETS].FA) INNER JOIN ([~ALLRWCBL] INNER JOIN [~ALLCBLEQ] ON" _
& "[~ALLRWCBL].Cable = [~ALLCBLEQ].Cables) ON [~ALLTARGETS].TARGET = [~ALLRWCBL].Cable" _
& "WHERE ((([~FIRE_AREAS].INDEX) = '" & currFA & "'))" _
& "UNION" _
& "SELECT DISTINCT [~ALLCBLEQ].Equipment, [~FIRE_AREAS].INDEX" _
& "FROM [~FIRE_AREAS] INNER JOIN (([~ALLTARGETS] INNER JOIN [~ALLRWCBL] ON [~ALLTARGETS].TARGET=[~ALLRWCBL].Raceway) INNER JOIN [~ALLCBLEQ] ON" _
& "[~ALLRWCBL].Cable=[~ALLCBLEQ].Cables) ON [~FIRE_AREAS].FULL_ID=[~ALLTARGETS].FA" _
& "WHERE ((([~FIRE_AREAS].INDEX) = '" & currFA & "'));"
Any help on the error and syntax improvement tips are greatly appreciated! Still learning!
Thanks!
Your string has no spaces between the lines so when you write:
sql = "SELECT DISTINCT [~ALLCBLEQ].Equipment, [~FIRE_AREAS].INDEX" _
& "FROM ([~FIRE_AREAS] …
That becomes a SQL string like
SELECT DISTINCT [~ALLCBLEQ].Equipment, [~FIRE_AREAS].INDEXFROM ([~FIRE_AREAS] …
Which is obviously invalid SQL because there's no space between INDEX and FROM.
An easy solution is just to put a space before each closing quote (or after each open quote):
sql = "SELECT DISTINCT [~ALLCBLEQ].Equipment, [~FIRE_AREAS].INDEX " _
& "FROM ([~FIRE_AREAS] …
However, If you find yourself writing relatively complex queries like this, I would recommend that you consider converting them to stored procedures or views instead.