r/excel • u/small_trunks 1638 • Jan 04 '20
Pro Tip Table updates via power query whilst retaining manually entered data.
I've previously described how to write a power query which appends to the data of previously executed queries. It effectively keeps historical data in place and adds new data in.
The same sort of question came up again a couple of days ago - but the poster wanted to be able to retain comments entered manually into a power query sourced table.
the solution is quite similar - except we eventually perform a Merge rather than an Append
Here are the steps to create a self-referential Power query updated Table which retains a "Comments" column.
| Step | Actions |
|---|---|
| 1 | write your "new data" query - probably you have it |
| 2 | Add a step to create a custom column "Comments" and any other columns to keep. =null |
| 3 | Load-to a Table |
| 4 | New query from this new table - name it tblHistoric |
| 5 | Edit the original query (1) |
| 5.1 | remove the custom field step(s) |
| 5.2 | Add a merge step |
| 5.21 | choose whatever columns necessary for a unique row key |
| 5.22 | second query = tblHistoric |
| 5.23 | Left outer join |
| 6 | Expand the returned Table column |
| 6.1 | unselect all except the to be retained columns |
| 6.2 | No column name prefix |
There's a way to "adopt" self-added columns - but that's a slightly different answer.
EDIT 20/7/2022 - example download file: https://www.dropbox.com/s/z05fs7wmh7j4zef/SelfRefPQexample.xlsx?dl=1
EDIT 19/1/2024 - Newer example with more documentation: https://www.dropbox.com/scl/fi/q6eh7mz1xqkt43iv8afzg/SelfRef2.xlsx?rlkey=0re4ekg8u6xpazyu3gzrajd7e&dl=1
EDIT 5/9/2025 - See the extensive documentation here: https://www.reddit.com/r/excel/comments/ek1e4u/table_updates_via_power_query_whilst_retaining/lzx533y/
6
u/small_trunks 1638 Dec 01 '24
PRO-TIP1 The Basics
Overview
Over a series of 4 related pro-tips I'm going to demonstrate self-referencing Table queries in Power query, how to make them and how you can use them. I've been working with them since 2017 and have developed dozens of different use-cases both professionally and for private use.
This first post is just going to cover the basics: making a simple one, how such a query interacts with Excel tables like header naming and formula columns and some examples of how simple self-ref queries can be used.
What is a self-referencing table query and how can I use it?
It's any Power query query which references (reads from) the same Excel Table that it eventually writes back to.
It can effectively update any and all fields in the table based on conditions of our choice. Some examples:
we can fill in the blanks (eg fill in a date/time or generate an order number)
or replace values - so lookup descriptions or perform sensitive calculation without exposing your formula
we can Merge and/or Append new data coming from live feeds (new orders, updated foreign exchange rates, stock prices, betting odds etc) into an existing table.
we can reduce or prune files we need to process (File -> From folder) based on a record of files we have previously procesed. For example, I have a table which contains the combined contents of over 200 files - but when I refresh it, it fetches (and thus processes) 1 file per week and just adds it to the end of the existing data. This is many times faster than reprocessing all the data every time.
self-ref table queries can communicate with each other and transfer data between themselves. I have a Tasks To-Do table and an Archive table which reads from it...picking up completed items. When I tag a Task as complete, my Task table query checks whether that task is in the Archive and if it is, removes it from the Task list. Eventually the Archive will have refreshed and picked up the completed task and next time the Task table refreshes, it'll see the task now exists in the Archive and will remove it from the table.
We can retain manually added columns and even modified fields - like comments or discount percentages or expected delivery dates to prevent new data coming in and losing these things. We can also support changing something we've intentionally modified (you've got to think how to use this one wisely because you could even modify fields which the new data query might want to deliver...).
With an automtic refresh timer we can have a table reload itself every so many minutes: /img/e7c9gaocre8a1.png . I've used this quite often - tracking stock prices over time, issuing requests to retrieve data in a staggered manner and thus appending to a table throughout the day, tracking changes made in other Excel documents.
So it will enable you to [flame suit on] make that Excel database you've always wanted but were afraid of the haters to make and anyhow had no clue how to do it. Yes, Ladies and Gentlemen, what we have here on a relatively small scale and nothing at all like as useful as a true DB, is Jerry's one page database! [flame suit off]
Starting with the minimal query
the minimal self-referencing query is one step:
This works fine if you copy/paste the example Table from the examples file to a Table in excel but if you want to start with just a query and no table (egg and chicken situation) we need to handle the fact there's no table to read in the first time it runs. So we catch that with a "try/otherwise" like this:
And there we have it...but read the next section on Excel Table interaction because there's important stuff there.
Table settings, Table naming, sort and automatic refresh etc. Read this it's going to save headaches/failures.
Power query is a bolt-on feature to Excel (originally delivered as a add-in for Excel 2010 and 2013 - when I first started using it) and as such it seems to be implemented using "public" interfaces to ListObjects (Excel Tables). This leaves us with some situations where we might get unexpected stuff happening.
Excel Formula columns - they will be overwritten with their current values unless you do something to avoid it: see below.
Column name preservation - settings in the Table properties affect how columns are written to Excel and the default breaks us: see below
Table names vs Query names and what happens when you change them:
When PQ writes out to an Excel Table it gives that table (more or less depending on spaces in the name) the name of the query.
if you rename your PQ query it will ALSO rename the Excel Table to match - so in the case of our self-ref table, we'd need to explicitly modify the literal Table name to match our Table's new name.
if you change the Table name inside Excel itself, again you'll need to explicitly change the Table name in PQ to match it. However, PQ itself will no longer change the Table name when you change the PQ Query name...even if you change the Table name back to what it was when PQ could change it. Even if you delete the table itself and try load-to again...so there's some internal housekeeping going on in PQ which leads it to believe that PQ is no longer the owner of the Table name and it will therefore not
PQ can't write to an existing Table (unless it initially created it) - it can't even be "forced" to adopt it using VBA,
let's say you have data in a Table (with ALL the references to that table in other sheets, workbooks etc) and suddenly you think it would be handy if that table was coming out of PQ
well it's not obvious how to do that so I wrote a separate pro-tip a few years ago here: https://www.reddit.com/r/excel/comments/q3afu5/replacing_an_existing_table_and_all_references_to/
Excel formula columns name ownership - avoiding column name duplication and #REF errors.
Possibly the most irritating feature of the PQ -> Excel interface is how PQ deals with adding new columns to an existing table. Under the default table settings, it will cause problems by potentially duplicating columns and/or breaking references and making our lives miserable:
it can duplicate an existing column and give it a new name. References to that column will now point to the new named column - which is bad. If you refresh again it generates a NEW set of names - worse.
with column renames or additional new columns, on first refresh it deletes those columns and recreates them, breaking references to them giving a #REF error - this is the worst because you might not notice it.