Retrieve Data from SQL with input from table - sql

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

Related

ACCESS VBA Unmatched Records Query Not Working When Concatenating

I have been trying to run a query from MS ACCESS VBA. My query works well when I don't add concatenated fields. When I use a concatenated field like in the code below, it turns an empty result.
Is there any work around?
lstStudentName.RowSource = "SELECT [sdtName] & ' ' & [sdtFatherName] & ' ' & [sdtLastName] AS sdtFullName, sdtID FROM tbl_sdt_Info " & _
" LEFT join tbl_sdt_Rounds ON tbl_sdt_Info.sdtID = tbl_sdt_Rounds.sdtID " & _
" WHERE IS NULL(tbl_sdt_Rounds.sdtID)"
Issues with your SQL:
Incorrect use of IS NULL - should be either IsNull(tbl_sdt_Rounds.sdtID) or tbl_sdt_Rounds.sdtID IS NULL. The latter is preferable because it is SQL, IsNull() is a VBA function.
Since there are two sdtID fields, query shouldn't work without table prefix to specify field. I am surprised you get anything.
Although possibly not an issue as is, my preference would be to make sdtID the first field and set ColumnWidths as 0";1.0" and first column as BoundColumn. This will allow viewing and typing first letter of name but sdtID will be listbox value.
Never hurts to build and test query object and when it works, replicate SQL statement in VBA.
lstStudentName.RowSource = "SELECT tbl_sdt_Info.sdtID, sdtName & ' ' & sdtFatherName & ' ' & sdtLastName AS sdtFullName FROM tbl_sdt_Info " & _
"LEFT join tbl_sdt_Rounds ON tbl_sdt_Info.sdtID = tbl_sdt_Rounds.sdtID " & _
"WHERE tbl_sdt_Rounds.sdtID IS NULL;"

Run one MS Access SQL script on a particular Table chosen by user

I have a MS Access 2016 database (*.accdb) with 20+ Tables. Fields in each of them vary slightly from Table to Table. I've no VBA experience, so I'm sticking only to the SQL query below (redacted).
SQL script
myvar below is the parameter I'd like to be prompted when the script is run so that I enter the Table I want the changes applied to.
PARAMETERS
[myvar] TableID;
UPDATE
[myvar]
INNER JOIN
Excel_Data ON [myvar].[Part Number] = Excel_Data.[Part Number]
SET
[myvar].[Value] = '?',
[myvar].Description = Excel_Data.Description,
[myvar].[Ref] = '?'
.
.
.
WHERE
[myvar].Description Is Null;
Output
Error message:
Too few parameters. Expected 0.
What I need
I prefer a solution for above in a SQL script form as above, not involving VBA, preferably. I'd like to enter the Table name when prompted so the script knows which table to UPDATE. FYI: The PARAMETERS work when it is not a Table as I've shown in my script above.
Help/advise is highly appreciated.
EDIT 1
Since it seems not possible to use parameters as Table names, could you suggest a VBA solution? A sample code, perhaps?
As said in the comments, you can't really solve this without VBA.
You can store your SQL query in a string, and use a placeholder to indicate the tablename. Then get the tablename using an inputbox and replace the placeholder with the tablename.
Dim sqlString As String
sqlString = "UPDATE [%Placeholder%] " & vbCrLf & _
"INNER JOIN Excel_Data ON [%Placeholder%].[Part Number] = Excel_Data.[Part Number] " & vbCrLf & _
"SET [%Placeholder%].[Value] = '?', " & vbCrLf & _
...
"WHERE [%Placeholder%].Description Is Null;"
sqlString = Replace(sqlString, "%PlaceHolder%", InputBox("Enter a tablename"))
CurrentDb.Execute sqlString
In a more mature solution, I'd create a form with a combobox containing all available table names, and add a function to sanitize tablenames (replace "]" with "]]")

MS Access VBA SQL SELECT * INTO tempTbl WHERE Stuff="" AND OtherStuff BETWEEN Date Range

I have a form with one text box, two combo boxes (dropdowns), and two text boxes with input masks for mm/dd/yyyy 99/99/0000;0;_
I am attempting to use all of these fields as filters for a subform.
I have the controls set to fire after update and run a sub that builds a SELECT * INTO sql string for a temp Table that is then sourceobject'ed back to the subform.
In code I have for each control I have code building a snippet of the Where statement for the final sql. the snippet grows as needed, is labeled "Filter"
Some other non-Finished Code....
If Not IsNull(txtDateFrom) Then
If i > 1 Then Filter = Filter & " AND " & "([Date_LastSaved] >= " & Me.txtDateFrom & ")" & " And " & "([Date_LastSaved] <= " & Me.txtDateTo & ")"
End If
Dim sql As String
sql = "SELECT * INTO tmpTable FROM tblReview"
If Not IsNull(Filter) Then
sql = sql & " WHERE " & Filter
End If
My issue and question is that I am testing this one specific situation where there will be Filter = Filter & " AND " & "DATE_STUFF"
where the final sql looks like...
SELECT * INTO tmpTable FROM tblReview WHERE ReviewStatus = 'Quoted' AND ([Date_LastSaved] >= 09/12/2018) And ([Date_LastSaved] <= 10/16/2018)
which should have some result with the test data. Yet, the tmpTable is empty.
This is only happening when I apply a date range criteria.
I tried BETWEEN but could not nail down the syntax.
Any insight is greatly appreciated, Thanks!
UPDATE:
Answer:
If i > 1 Then Filter = Filter & " AND " & "([Date_LastSaved] >= #" & Me.txtDateFrom & "#)" & " And " & "([Date_LastSaved] <= #" & Me.txtDateTo & "#)"
If you want to use dates then they must be quoted. If you just say 10/16/2018 then you are dividing the integer 10 by 16 by 2018 which will yield an integer zero. It will then convert the dates to an integer to do the compare, which will yield a much bigger number, and thus you get no rows.
Any date testing should always be done using date types rather than strings. I think in msaccess you can surround it in #, but not sure. Just research this.

Get VBA to Evaluate Formula In String

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.

How to "order by" a column and "Include Column Name with query"?

I am trying to run a sql query in excel and I want to :
1. order the query result by my column "Stationname"
2. include the column names with the query
Right now it is returning all the columns without the column name, and the end users do not know what it is.
Could someone please help? I am stuck! Below is my current code:
strQuery = "select pipelineflow.lciid lciid, ldate, volume, capacity, status, " & _
"pipeline, station, stationname, drn, state, county, owneroperator, companycode, " & _
"pointcode, pointtypeind, flowdirection, pointname, facilitytype, pointlocator, " & _
"pidgridcode from pipelineflow, pipelineproperties " & _
"where pipelineflow.lciid = pipelineproperties.lciid " & _
"and pipelineflow.audit_active = 1 " & _
"and pipelineproperties.audit_active =1 " &
_
"and pipelineflow.ldate " & dtInDate & _
"and pipelineproperties.stationname = '" & Stationname & "' "
For part 1 of your question, add an ORDER BY clause to your query. In this case: order by stationname
Part 2: Not sure why column names aren't being included in your query. You can explicitly name a column using something like the following (purely an example):
select mycolumn as "MyCustomizedColumnName" from mytable
That allows you to give columns names of your choosing. Having said that, you shouldn't be required to do so for every column, so I suspect something else is going on in your case.
I should probably add that a stored procedure (rather than dynamic SQL) will yield better runtime performance.
For ordering just put
Order By stationname
at the end of the Query.
You can iterate through the column names by using:
rst(1).Name
where rst is your recordset, and the number is the index of the column.
To sort your query results , use 'ORDER BY' at the end of the query. The last lines of your query would look like this
"and pipelineproperties.stationname = '" & Stationname & "' " & _
"ORDER BY pipelineproperties.stationname"
The column heading are returned in your query data, but not automatically written to the Excel worksheet. The code snippet below shows how to loop through the recordset's column headings and write them to the active cell's row.
'rst' refers to your recordset, update the name as required.
If Not rst.EOF Then
For x = 0 To rst.Fields.Count - 1
With ActiveCell.Offset(0, lcount)
.Value = rst.Fields(x).Name
End With
Next
End If
Make sure that you offset down from the active cell when writing the query results to the worksheet, otherwise your headings will be overwritten by the data.
Activecell.Offset(1,0).CopyFromRecordset rst