I recently built a cool Excel solution at work that uses Power Query to reach out and grab some weather data, then upload it into database. We use that data in our dashboards, as weather is pretty important to the golf industry in which I work. But then I went to deploy the file, and needed to find a way to tame the Power Query Workbook Privacy settings.
What happens is, every time a user runs a Power Query that was last saved by another user, they are prompted to set the Workbook’s Privacy level. This is maddening, as we have two staff that use this workbook, where one covers for the other while they’re away. Naturally, long lapses of time can occur in between… just long enough to forget what to do when you’re prompted by this frustrating message:
So while I can (and have) set the privacy level for the web data they are going to retrieve (see my tool here), I have no way to permanently set the Workbook’s Privacy level. Worse is that, if the user clicks Cancel, or chooses the wrong privacy level, (even trying to protect the output table structure using Chris Webb’s technique here,) fails. The table generates an error, and all business logic in the workbook is blown apart. The only recourse is to exit the file without saving and try again.
Naturally, this concerns them, and they call to make sure they do the right thing. That’s awesome, and I wouldn’t change that at all. But the deeper underlying problem is that Power Query’s Workbook security is engineered to require developer interaction. And that is bad news!
How to Tame Power Query Workbook Privacy Settings
Unfortunately I can’t use VBA to set this in the workbook (or at least, I haven’t tried, anyway), but I can work a little trick to at least warn my users when they are about to be prompted, and remind them which privacy level they need to select. Here’s what I need to do in order to make that work:
Step 1: Create a range to hold the last user
- Create a named range somewhere in the workbook called “rngLastUser” (I put mine on the “Control Panel” worksheet and hid it.)
- Drop the following code in a Standard VBA Module:
Public Sub UpdateLastUser()
.Range("rngLastUser") = Application.UserName
Step 2: Create a macro to update your Power Queries
- Cook up a macro to refresh the connections (here’s a way to update all connections from my last blog post). For this purpose, I’m going to update just the “WeatherHistory” table on the “Weather” worksheet:
Public Sub GetWeather()
'Check if privacy level will need to be set
If .Worksheets("Control Panel").Range("rngLastUser") <> Application.UserName Then
MsgBox "You are about to be prompted about Privacy Levels" & vbNewLine & _
"for the Current Workbook. When the message pops up, " & vbNewLine & _
"you'll see an option to 'Select' to the right side of the Current Workbook." & vbNewLine & _
vbNewLine & _
"Please ensure you choose PUBLIC from the list.", vbOKOnly + vbInformation, _
"Hold on a second..."
'Refresh the Power Query table
Step 3: Link the macro to a button for your users
- Link my GetWeather() routine to a button
- And we’re good!
What Did We Do?
So basically, what I did here was this:
- Every time the user clicks the button…
- Excel checks the contents of rngLastUser to see if the username is the same as the current user
- If it is, it just goes on to refresh the table
- If it’s not, it kicks up the following message:
- After the user clicks OK (if necessary), then it prompts the user to set the security level. Yes, they can still get it wrong, but at least they have a chance now!
- Once the security level is set, the macro goes on to refresh the table
- After the table is refreshed, Excel updates the rngLastUser cell to the name of the current user.
And that’s it. We now have a system that will prompt our users with the correct answer, so that they don’t have to come back and ask us every time.
Thoughts On The Security Model
Ideally it would be nice to not have to do this, and there is – in fact – a way. Microsoft’s answer is “Yes, just enable Fast Combine.” That’s great and all, but then it ignores all privacy levels and runs your query. What if, as a developer, I need a way to ensure that what I’ve built stays Public, Private or Organizational? What it if actually matters?
To me, Fast Combine is akin to setting Macro Security to Low in Excel 2003 and earlier. Basically, we’re saying “I don’t like nagging messages, so let’s run around in a war zone with no bullet proof vest.” Sure, you might come out alive, but why should you take that risk?
In my opinion, the Power Query security model needs work. Even if we could assign a digital certificate to the query to prove it (and the privacy levels) had not been modified, that would be great. I’m not sure exactly what it is we need, but we need something better than what we have today.