I want to load a table data from SQL data bases by Excel ODBC, but the condition "where" i wanted to be dynamic - depended on excel spread cell "A1".
I made somethin like this:
a picture link
select * from tabel where id = ?
But this doesn't work and i donno how to define "?" as A1 Cell
Say you have the following query that works:
If you add a WHERE CLAUSE like so:
Then press OK it should prompt you to refresh your query.
At that point you should get the following dialog, which you can use to set your parameter.
Related
I would like to use an Excel cell to change the reference data in a Where statement so that I don't have to keep going into power query to change the statement.
Instead of the 31690 in the below code I would like to reference cell B7 in sheet1 of the same Workbook instead.
Is this possible? and if so how?
Thanks in advance.
WHERE ORDERDATE >= #Month13#(lf)#(tab)and STOCKCODE is not null#(lf)#(tab)AND SALESORD_HDR.ACCNO = '31690'
Maybe something like this?
For this approach to work, you need to make sure your spreadsheet has a table and the table's range starts with A1 and spans beyond the cell with the value in it--in this case, B7. Here's an example:
I started by creating this spreadsheet with a table named Table1:
Then, I used Table1 as the source in Power Query.
Notice that with the table above, what was row 7 is row 6. This is because the column headers don't have row numbers in Power Query. This change in row numbering matters for finding your targeted cell.
Then I added some custom M code. This code first extracts the second column's name from the list of column names. (Because the second column would be column B of the spreadsheet.) Then it uses that second column's name to create a table of that column's values, from which it then extracts the sixth row entry. (Because that sixth row entry would be the seventh row entry in the spreadsheet.) Note that the {1} points to the second column and the {5} points to the sixth row. That's because Power Query indexing starts at 0.
I went into Advanced Editor and renamed the step from Custom to DateVariable:
DateVariable = Table.Column(Table1_Table, Table.ColumnNames(Table1_Table){1}){5},
Then I added some more custom M code to concatenate the DateVarable with the rest of your SQL statement as an example:
Here's my M code:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
DateVariable = Table.Column(Source, Table.ColumnNames(Source){1}){5},
SQL_Statement = "WHERE ORDERDATE >= #Month13#(lf)#(tab)and STOCKCODE is not null#(lf)#(tab)AND SALESORD_HDR.ACCNO = '" & Text.From(DateVariable) &"'"
in
SQL_Statement
Simple solution using a named range
First, select cell B7 and enter a name in the Name Box (e.g. CellReference). Then right-click on the cell and click on Get Data from Table/Range.
This opens the Power Query Editor with a query that returns a table containing the cell from the named range. Open the advanced editor, delete the entire content of the query and type Text.From(Excel.CurrentWorkbook(){[Name="CellReference"]}[Content][Column1]{0}) and click on Done, this is what it should look like:
Note: Text.From() is used so that value returned by CellReference can be concatenated with the SQL query using &. Also, this function is preferable to Number.ToText() which does not work with text values.
Finally, insert the query name in your SQL query: WHERE ORDERDATE >= #Month13#(lf)#(tab)and STOCKCODE is not null#(lf)#(tab)AND SALESORD_HDR.ACCNO = "&CellReference
Note that if the cell contained a text value instead, then you would need to adjust the syntax like this: ... SALESORD_HDR.ACCNO = '"&CellReference_Text&"'"
How to deal with warnings: new query permission and Formula.Firewall
How to give permission to run all new native database queries
Depending on your Query Options settings, you may get this warning message regarding the permission to run the modified SQL query each time CellReference contains a new value:
If you are certain that the cell will never contain a string of characters that could modify the database, you can disable this warning message by going to File -> Options and settings -> Query Options. Under GLOBAL, go to Security and uncheck Require user approval for new native database queries.
Note that this is a global setting that is immediately applied to all your Excel files, including those that are currently open.
How to disable the Formula.Firewall warning message
Depending on your Privacy Levels settings, you may get a Formula.Firewall warning message preventing the query from being executed:
If you are in a situation where you can disregard privacy levels, you can disable this message by going to File -> Options and settings -> Query Options. Under CURRENT WORKBOOK, go to Privacy and select Ignore the Privacy Levels and potentially improve performance.
Click on OK and refresh the query.
If, on the other hand, your workbook needs to preserve a privacy level of Private or Organizational, to my knowledge there is currently no way of integrating CellReference to a SQL query (even using a SQL parameter set with the Value.NativeQuery function or a Power Query Parameter ) without raising this warning message. The only solution would be to include CellReference in another step in the query, but then the filtering will occur in Power Query and not at the server level: query folding is interrupted when a step includes a query/function/parameter that is linked to an external data source including a named range in the workbook itself.
If your workbook privacy level is set to Public, you should be able to avoid this warning message by using the Value.NativeQuery function (you can even enable query folding for further query steps if you are using a SQL Server or PostgreSQL database). If you still get the warning message, you can try combining the two queries accessing each data source (the database and the worksheet) into a single query.
Note: these steps were tested with Excel Microsoft 365 (Version 2107) on Windows 10 64-bit connected to a local SQL Server 2019 (15.x) database.
This answer was prepared by referring to many blog posts by Chris Webb (linked above) and by Ken Puls (like this one).
I'm having some trouble passing a particular type of parameter from an Excel cell value to an ODBC query. It's a DB2 database on an AS400 server, and I'm using the iSeries Access ODBC Driver from IBM.
Here is the query with hard-coded values:
SELECT STKB.BXPART, STKB.BXSTOK, STKB.BXQTOH, STKB.BXUNIT
FROM CMSDAT.STKB STKB
WHERE (STKB.BXPART In ('BAG024','BAG709'))
And the desired result:
What i would like to do is pass the list from an Excel value to the parameter. The query is modified like so:
SELECT STKB.BXPART, STKB.BXSTOK, STKB.BXQTOH, STKB.BXUNIT
FROM CMSDAT.STKB STKB
WHERE (STKB.BXPART In (?))
And the parameter is set to pull from a cell:
If I put one value in the cell, the query returns the results for that one value. If I try more than one item the query returns empty. I've tried the following values in the cell AA4:
('BAG024','BAG709')
(BAG024,BAG709)
'BAG024','BAG709'
BAG024,BAG709
Has anyone successfully used cell values for an 'in' parameter?
Thanks!
I used ODBC to create a sheet in Excel and add a row to it.
Literally the commands were just:
create table 'update5' ('age' NUMBER);
insert into 'update5'.'age' values (1);
This works and I can see the rows in the sheet and via DBVisualiser and my ODBC query results.
Later, I wrote more SQL to add another row like so:
insert into 'update5' ('age') values (2);
but I get the error:
[Microsoft][ODBC Excel Driver] Cannot expand named range.
I do not know why named ranges are being used, is there a way I can set ODBC to not use them?
Without knowing more about what your doing, what you're working with, and your end-goal I can't give a definite answer - however, if you're saying this works fine as-is:
create table 'update5' ('age' NUMBER);
insert into 'update5'.'age' values (1);
...then it stands to reason that this:
insert into update5 values (2);
...will not work because your missing:
quotation marks (which may or may not be optional in your environment), and,
the field name to which you want to export.
In the first insert into statement you have:
'update5' <-- the destination table
.'age' <-- the destination field
values (1); <-- the value to insert
...so if you're just trying to add a record with the number 2 to the same field, use the same code:
insert into 'update5'.'age' values (2);
More Information:
w3schools : SQL INSERT INTO Statement
TutorialsPoint : SQL INSERT Query (Tutorial)
Found it.
When you create an table in Excel via ODBC you create a named range of the same name within that table.
When you try to insert like this:
insert into 'update5'.'age' values (2);
It is interpreted as you trying to add to the the named range called update5 which is inside the table update5.
You need to use the syntax:
insert into [update5$].'age' values (2);
to add values to the table called update5.
Access and Excel 2013
Trying to use an Access base as a data source in Excel, it seems like if a query calls a VBA function, Excel doesn't see it.
This query shows up in Excel:
SELECT "StaticValue" AS static_value;
This one doesn't:
SELECT my_function() AS value_from_vba;
The code of the module containing my_function being:
Option Compare Database
Function my_function() As String
my_function = "ValueFromVBA"
End Function
How can I call a VBA function in an Access query and link this query to Excel ?
Hmm perhaps;
Make table and query the table (as stated in comments)
My preferred is just to export the data from access into a new worksheet that you need in excel, then you can do what you want with it if you are only getting values. Then you can go back in and update anything after (in your access tables) with VBA should you need it
I ended up creating a table (SELECT … INTO …) that I refresh on a regular basis. This table is linkable within Excel. It is probably a dirty trick, but it does the job.
I would love to know how to import a single value from my Access database into an Excel cell.
Alternatively removing the header would be a good start.
The query
SELECT SUM(DEMANDS) AS TOTAL FROM [DB PROD]
gives me a header named TOTAL and, right below it, the sum I'm interested in. I use this query from within Excel (Data > Get External Data > From Access). How can I only get the sum in a single Excel cell?
One way to accomplish your goal would be to put your existing query on a different Sheet, say Sheet2, so the column header appears in Sheet2!A1 and the value appears in Sheet2!A2. Then reference the value cell from elsewhere in the Excel document. (The formula will look something like =Table_test.accdb[TOTAL].)
If you had several queries you could presumably keep them together (side by side) on the same sheet. You could also hide the query sheet so the "magic" would be more transparent to the user.
I am not sure I understand what you are doing, but, in order to read Access data from Excel, you need to do the following:
programmaticaly open a connexion in your Excel code, pointing to your
access database (let's say an ADO connexion for example)
then execute your 'SELECT' through this connection, using the ADODB.command object. That will return the requested value
another option would be to open a local recordset in Excel,based on your SQL intruction, and read the value.
Then do not forget to close your connexion