Update data by an external reference (link) to a table in another workbook - excel

I have defined a table Table1 in source file.xlsx. When source file.xlsx is open, in target file.xlsx, I could use ='source file.xlsx'!Table1[#Data] in a cell to get the table data.
However, I realise that if I close source file.xlsx, that formula becomes ='\\Mac\Home\Downloads\source file.xlsx'!Table1[#Data] and its value becomes #REF!.
This is not the case for an external reference (link) to a cell range in another workbook; an external reference to a cell/range could still get value when the source file is closed.
Could anyone tell me how to update the table data even though when the source file is closed?

This is expected behaviour
From the Microsoft Help
Links to data tables residing in external files display #REF!
Symptoms
Consider the following scenario:
You insert a table in an Excel file, named for example source.xlsx.
In another file, named for example destination.xlsx, you insert a link to the data table which resides in source.xlsx.
You close both source.xlsx and destination.xlsx.
You open destination.xlsx and you choose to update links when prompted.
Result: the cells that are linked to the external data table display #REF!.
Cause
This is expected behavior for Excel.
New references to external workbooks that aren’t open will successfully parse without verifying the reference, but will return #REF.
When loading an external structure reference to a closed workbook, the reference is not updated by default. If you choose to calculate the formula the result is #REF! instead of the corresponding value.
Microsoft Help
As an alternative, create a query to the table. This can be refreshed from a closed workbook

To answer your question:
What you are seeing is how excel works at a cell formula level. If you type in
=[file.xlsx]Sheet1!Table1[#All]
This might be a little more of what you want, but it will give you the whole table.
For one column you can do:
=file.xlsx!Table1[[#Headers],[Date]]
=file.xlsx!Table1[Date]
You can create a defined name for Table1 as mytable then you would enter the formula =file.xlsx!mytable
All the above becomes similar to ='\\Mac\Home\Downloads\source file.xlsx'!Table1[#Data]
For an alternate method (recommended):
The very best way I have found to do this is using power query. This is not formulas in cells but it is like a database query tool. There are several people on You-tube making videos about using power query for this exact thing. I will step you through the process starting in the file where you want the data to appear. Go to:
Data > (Get & trasform Data) Get Data> From File> From Workbook...
In the popup window navigate to your file "\Mac\Home\Downloads\source file.xlsx" and click Import.
In the next window choose "Table1" (or an item that you want).
Now choose load and this data loads into your sheet.
If you want to transform the data of "Table1" then...
Data > Queries & Connections> (this pops open a "Queries & Connections")
Right click on Table1 then edit.
There are many options to choose from such as: remove columns, filter...
To calculate new columns use > Add Column which uses M function.
For Vlookup use Merge Queries,
For a Count, Sum, Average, or ... of rows (utilizing one or multiple columns) use "Group by".
After you "Close & Load" the table gets updated. If new values get entered into file.xlsx Table1, refresh the power query table and the data shows up.

Related

Reference an excel cell in a Where statement to change the Query

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).

Updating a table from a power query changes formula reference

Saw this was previously asked here on SO and had no solution and I can't find a solution through Google either.
I have a workbook with a tab called "Data" containing a table which is updated via a power query and another tab called "Calcs" with formulas referencing the cells in the table from "Data". When I refresh the table, it pulls data via the power query, but when it's done, the formula references change.
For example, before the refresh, I'll have formulas like this in the "Calcs" tab:
=COUNTIFS('Data'!$A$2:$A$26886,$A1060,'Data'!$K$2:$K$26886,'BY CAT'!$B1060)
After the refresh, the references for column A only change to
=COUNTIFS('Data'!$A$10242:$A$26886,$A1060,'Data'!$K$2:$K$26886,'BY CAT'!$B1060)
And it results ina #VALUE! error message.
How can I prevent Excel from creating this reference shift?
You might be able to get around this by using full column references:
=COUNTIFS('Data'!$A:$A,$A1060,'Data'!$K:$K,'BY CAT'!$B1060)
Full column references aren't always a good idea, but it might just work in this case.
Edit:
Table column references would be ideal, TableName[ColumnName]. These should work given that you are reading from a power query generated table.

How do you copy the powerpivot data into the excel workbook as a table?

I have data in powerpivot that I've modified and I'd like to place it into the workbook as a regular table (and not as a pivottable). I need this so that I can run use the table for some vlookups from another worksheet in the same workbook.
I found this answer: link which I will try and summarize with out cutting and pasting to much. This assumes you have powerpivot installed.
goto powerpivot and "import from and external source" the data you want to munge and bring back into the workbook as a table
Key here is to select the checkbox “Enable selection of multiple tables”.
when prompted at the "import data" window, pick pivot report (you won't really use this)
go back to powerpivot with the "Manage Data Model:
add a new measure below your data. something like: NRofOrders:=COUNTROWS(values(FactResellerSales[SalesOrderNumber]))+0
(you won't really use this but this seems to change the query to this table so that you can use DAX)
also add any columns that you want ( for me, this is want I wanted that I wanted to be reflected back in the workbook)
back to Excel, select the data tab, click on Existing connections and select Tables: and then pick a table from your query.
boom, you're done
(the link continues on and you should read that as it's interesting but at this point you should have powerpivot query with your modification as a table in your workbook)
The July 2014 update to Power Query (pushed out at the end of Aug) simplifies the answer. With the new Power Query Update you can pull the data into the Data Model with out having to also copy it to the Works sheet.
goto powerquery and import the data you want to munge. Use the option to just add it to the Data Model.
go back to excel and then go to powerpivot with the "Manage Data Model" button.
munge your data (add columns, whatever)
back to Excel, select the data tab, click on Existing connections and select Tables: and then pick a table from your query.
boom, you're done
In the PowerPivot window you can select the table, or elements of it, and then copy (nornal right click or ctrl +c) and paste that into your spreadsheet.
This works for reasonable amounts of data but if you try and do it with thousands of rows you may find that excel objects and falls over, based on my experience.
Vlookups kind of defeat the purpose of PowerPivot :-)
Found a great solution over on Mr Excel
(http://www.mrexcel.com/forum/power-bi/637919-extracting-static-data-powerpivot-without-pivot-tables.html)
If you are trying to get a PowerPivot table into Excel, then you can simply query it. The easiest way to set that up is to first create any pivot table based on you PowerPivot data. Then double-click the measures area to drill-through. This creates a table with a connection to your PowerPivot model. Then edit the command text by going to: Data > Connections > Properties > Definition tab > Command Text.
Change it to something like
Code:
EVALUATE Table1

SSIS - How do I read an Excel file STARTING from a specific row?

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

Import a single value from Access into Excel (without the column heading)

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

Resources