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.
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 am using ODBC to connect to Excel via my DSN which has a default worksheet configured.
I can create pages in the worksheet via the create table command like this:
CREATE TABLE testtable( c VARCHAR(8) )
However when I use the drop table command like this:
DROP TABLE testtable
The Execute function returns a success value but the sheet is not deleted. The column name has been removed but that is all.
Anyone know what might be wrong?
This is a limitation of the Excel ODBC driver - the DROP statement will clear the worksheet, but not delete it.
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.
The Excel file I receive is very "irregular" ... the first few rows are just descriptions and random information.
I want to start reading the file from row #17 and ONLY visible rows.
Row 17 is the header for the columns (like a normal table).
Is such a thing even possible?
In the excel connection you can set openRowset, selecting cells from your sheet like Excel,
Example: openRowset: Sheet1$A17:f30
Check this link add the script counter to your package then you can do a conditional split task for MyCounter > 17, if you do this straight after the import it should contain the correct rows.
I'm not sure what you mean by visible rows though. If you get rows that are fully Null then you can always add that to the condition.
The excel file can be queried like sql statement. In your data flow task, take excel source set the conncetion manager as excel then data access mode as sql command. write the query on excel.
Example
Consider your worksheet name as Sheet1, having columns ID, Name, Dept and your data starts from 17 write the query like this
SELECT [ID],[Name],[Dept] from [Sheet1$A17:C65536] Where [ID] is not null.
This query selects data from row 17 to end of the excel until where data exists.
If your header row is A17 dont forget to check "first row has column names" in connection manager.
I have created 2 variable one for File Name and other for Sheet Name and store the values from “for each loop” container to it.
I have made an Excel Connection manager and then take the sheet Name from variable which I have created in variable:
Now I have select Data Access mode as “SQL command from variable”.And then Select variable Name from drop down.
I have to read data from query_2 which I have created in Variable and in which i have used sheet name as variable "SELECT * FROM "+"["+REPLACE(#[User::FileName],".XLSX","$A35:R]")` to Select the range of data which is available in sheet .
Click here for a clear explanation with example
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