Excel vba обновить запрос

Файлы к уроку:

  • Для спонсоров Boosty
  • Для спонсоров VK
  • YouTube
  • VK

Ссылка:

  • Страница курса
  • Плейлист YouTube
  • Плейлист ВК

Описание

Мы хотим при помощи VBA обновить запросы выборочно. Напишем несколько простых VBA скриптов.

В первом скрипте мы просто научимся выводить на лист Excel названия всех подключений.

Во втором скрипте мы обновим запросы выборочно прямо в коде указав, какие запросы обновлять не нужно.

Для третьего скрипта мы предварительно создадим таблицу Excel с перечнем запросов для обновления.

Код

Код для вывода на лист Excel всех запросов в книге:

Sub ShowConnections()
    
    Dim Connection As WorkbookConnection
    
    rn = 1
    
    For Each Connection In ThisWorkbook.Connections
        Range("A" & rn).Value = Connection.Name
        i = i + 1
    Next Connection
    
End Sub

Код для обновления запросов выборочно с указанием запросов, которые обновлять не надо:

Sub RefreshConnections()
    Dim Connection As WorkbookConnection
    
    For Each Connection In ThisWorkbook.Connections
        If Not Connection.Name = "Запрос — pop_1" Then
            Connection.Refresh
        End If
    Next Connection
    
End Sub

Код, для которого мы предварительно создали таблицу с перечнем запросов к обновлению:

Sub RefreshSelectively()
    Dim Connection As WorkbookConnection
    Dim rng_Refresh As Range
    
    Set rng_Refresh = Range("Обновить_Запросы[Обновить_Запросы]")
    
    For Each Connection In ThisWorkbook.Connections
        If Not rng_Refresh.Find(Connection.Name) Is Nothing Then
            'MsgBox rng_Refresh.Find(Connection.Name).Address
            Connection.Refresh
        End If
    Next Connection
End Sub

Курс Power Query + VBA

Номер урока Урок Описание
1 Power Query + VBA №1. Обновить запросы выборочно, обновить все запросы кроме одного В этом уроке мы научимся выборочно обновлять запросы в книге Excel с помощью VBA.
2 Power Query + VBA №2. Путь к файлу папке при помощи VBA В этом уроке вы узнаете как задать путь к файлу-источнику для Power Query при помощи VBA.
3 Power Query + VBA №3. Обработать и сохранить много файлов В этом уроке вы узнаете как по очереди обработать и сохранить каждый нужный вам файл. Это еще один распространенный способ применения VBA в связке с Power Query.
4 Power Query + VBA №4. Обработать множество ссылок по одной В этом уроке вы узнаете как обработать большое количество web-страниц по одной, чтобы избежать ошибок и разрывов.

Хитрости »

12 Январь 2023              878 просмотров


С выходом Power Query в массы все чаще стал появляться вопрос: как обновить запросы один за другим в заданном порядке?

Если еще не работали с этой надстройкой и не знаете что это такое, то для начала лучше ознакомиться со статьей: Power Query — что такое и почему её необходимо использовать в работе?
Описание проблемы

В книге может быть десять и более запросов. И только 4 из них надо обновлять постоянно, да еще и в заданном порядке. Например, у нас есть с десяток запросов по продажам, отгрузкам и прочей аналитике, но только 4 из них нам надо обновить. При этом обновить надо в строгой последовательности:

«Запрос — Отделы», «Запрос — Сотрудники», «Заказы и Продажи», «Запрос — Бюджет»

. При этом обязательно необходимо, чтобы «Запрос — Бюджет» обновился последним, т.к. он зависит от всех остальных.

Какие есть варианты решения?

  • Вручную
  • Кнопка Обновить все(Refresh All)
  • Написать собственный порядок обновления через Visual Basic for Applications

 
Что еще может пригодиться в решении задачи:

  • Вывести список имен имен всех подключений на лист

Обновление вручную

Можно обновить запросы стандартными методами, поочередно вручную обновляя каждый запрос. Но это не всегда удобно, особенно если запросов более 5. Значит этот вариант не разбираем в деталях в принципе — все его плюсы и минусы очевидны.


Данные -Обновить все

Кнопка Данные(Data)Обновить все(Refresh All) не просто обновляет все без исключения запросы в книге, но и порядок запросов при этом никак не определить, следовательно мы не можем быть уверены в том, что обновление произошло именно в нужном нам порядке. Но все же не станем отбрасывать этот вариант как не рабочий — если проблема лишь в порядке обновления, то решение все же есть.
На самом деле, если мы имеем дело с Power Query, то правильнее всего выстраивать все взаимосвязи уже на стадии создания этих запросов в любом случае. Т.е. создавать их в правильной последовательности и «затягивать» данные в основной запрос в самую последнюю очередь, ориентируясь на результаты вспомогательных запросов. Это оптимальный вариант, т.к. в этом случае достаточно будет просто обновить нужный запрос, а Power Query сама определит какие вспомогательные запросы необходимо обновить для корректного результата. При этом встроенный механизм Power Query достаточно хорошо справляется с кешированием данных и даже если обновление происходит через кнопку Обновить все(Refresh All), то даже если на один и тот же вспомогательный запрос будет завязано несколько других — он будет обновлен лишь один раз, а не при обновлении каждого запроса.
Но здесь у нас опять же возникает проблема — если нам не надо обновлять все запросы в книге — как Power Query узнает, какие из них надо обновлять, а какие нет? Ответ — никак. Поэтому хоть и следует всегда стараться выстраивать цепочки взаимодействий запросов в «правильном» порядке — нашу проблему с обновлением только части запросов это никак не решит. В этом случае можно создать мастер запрос, в который просто через объединение запросов собирать все нужные. И обновление этого запроса должно инициировать обновление всех указанных в нем запросов со всеми их цепочками. Как создать подобный мастер запрос:

Все, запрос готов. Теперь достаточно обновить только его, чтобы все связанные запросы обновились. Правда, есть одна проблема: если данных много, то такой запрос их увеличит вдвое — ведь мы в один запрос собираем все остальные…


Собственный порядок обновления через Visual Basic for Applications

В решении через мастер-запрос есть одна проблема — запросы могут быть не только Power Query, но и более старых версий. Здесь вариантов вообще не остается — только Visual Basic for Applications. Да и в случае, если запросы уже созданы ранее кем-то еще или навыков создать мастер-запрос нет.

'---------------------------------------------------------------------------------------
' Author : Щербаков Дмитрий(The_Prist)
'          Профессиональная разработка приложений для MS Office любой сложности
'          Проведение тренингов по MS Excel
'          https://www.excel-vba.ru
'          info@excel-vba.ru
' Purpose: Код обновляет поочередно указанные запросы в заданном порядке
'---------------------------------------------------------------------------------------
Sub RefreshConnections()
    Dim oc, xQuery, aConnections, xConName
    Dim IsBG_Refresh As Boolean
    'создаем перечисление всех запросов, которые надо обновить
    'располагаем их в том порядке, в котором необходимо обновлять
    aConnections = Array("Запрос — Отделы", "Запрос — Сотрудники", "Заказы и Продажи", "Запрос — Бюджет")
    'перебираем и обновляем все запросы поочередно
 
    For Each xConName In aConnections
        Set oc = ActiveWorkbook.Connections(xConName)
        Set xQuery = Nothing
        Select Case oc.Type
        Case Excel.XlConnectionType.xlConnectionTypeODBC
            Set xQuery = oc.ODBCConnection
        Case Excel.XlConnectionType.xlConnectionTypeOLEDB
            Set xQuery = oc.OLEDBConnection
        Case Else
            'запрос выгружен в таблицу на листе
            If oc.Ranges.Count > 0 Then
                Set xQuery = oc.Ranges(1).QueryTable
            End If
        End Select
        'непосредственно обновление запроса с ожиданием окончания обновления
        If Not xQuery Is Nothing Then
            'запоминаем значение обновления в фоне для запроса
            IsBG_Refresh = xQuery.BackgroundQuery
            'выставляем принудительно ждать завершения запроса
            xQuery.BackgroundQuery = False
            'обновляем запрос
            xQuery.Refresh
            'возвращаем обновление в фоне в первоначальное состояние
            xQuery.BackgroundQuery = IsBG_Refresh
        End If
    Next
End Sub

Как использовать: Для начала надо убедиться, что разрешены макросы и при необходимости включить их: почему не работает макрос. Затем копируем код выше, из Excel переходим в редактор VBA(Alt+F11) —InsertModule. Вставляем туда скопированный код. Теперь код можно вызывать нажатием клавиш Alt+F8 -выделяем RefreshConnectionsВыполнить(Run).
Чтобы использовать приведенный код для своих запросов достаточно в строке:

aConnections = Array("Запрос — Отделы", "Запрос — Сотрудники", "Заказы и Продажи", "Запрос — Бюджет")

внутри Array() перечислить в кавычках через запятую все имена запросов, которые необходимо обновить. Перечислять надо сразу в том порядке, в котором их требуется обновлять.
Код обновляет не только запросы Power Query, но и запросы более старых версий, выгруженных просто на лист.


Вывести список всех запросов в книге на лист

Что делать, если

я не знаю, как правильно называются запросы

Да, вполне логичная ситуация, когда запросов много и переписывать имя каждого запроса не такая уж простая задача. Очень легко ошибиться в имени и тогда обновления не будет. Поэтому ниже я прилагаю код, который выводит на новый лист имена всех запросов:

'---------------------------------------------------------------------------------------
' Author : Щербаков Дмитрий(The_Prist)
'          Профессиональная разработка приложений для MS Office любой сложности
'          Проведение тренингов по MS Excel
'          https://www.excel-vba.ru
'          info@excel-vba.ru
' Purpose: Код выводит на лист все запросы в текущей книге
'---------------------------------------------------------------------------------------
Sub GetAllConnections()
    Dim ws As Worksheet
    Dim lr As Long
    Dim oc, aList()
    'создаем массив для запоминания имен всех запросов
    ReDim aList(1 To ActiveWorkbook.Connections.Count, 1 To 1)
    For Each oc In ActiveWorkbook.Connections
        lr = lr + 1 'увеличиваем счетчик
        aList(lr, 1) = oc.Name
    Next
    'создаем новый лист, в который записываем имена всех запросов
    Set ws = ActiveWorkbook.Worksheets.Add(before:=ActiveWorkbook.Worksheets(1))
    'оформляем заголовок(для эстетики)
    ws.Cells(1, 1).Value = "Имя запроса"
    ws.Cells(1, 1).Font.Bold = True
    'записываем имена всех запросов
    ws.Cells(2, 1).Resize(lr, 1).Value = aList
End Sub

Статья помогла? Поделись ссылкой с друзьями!

  Плейлист   Видеоуроки


Поиск по меткам



Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика




  • 2014-10-22




  • Ken Puls




  • Categories:

    Excel, Power Query, VBA

When I’ve finished building a solution in Excel, I like to give it a little polish, and really make it easy for my users to update it.  The last thing I want to do is to send them right clicking and refreshing everywhere, so I program a button to refresh Power Query with VBA.

The interesting part about the above statement is that Power Query doesn’t have any VBA object model, so what kind of black magic trick do we need to leverage to pull that off?  As it turns out, it’s very simple… almost too simple in fact.

A Simple Query

Let’s just grab the sample data file from my post on pulling Excel named ranges into Power Query.  Once we’ve done that:

  • Click in the blue table
  • Go to Power Query –> From Table
  • Let’s sort Animal ascending (just so we know something happened)
  • Next save and Exit the query

At this point, we should get a new “Sheet2” worksheet, with our table on it:

SNAGHTML34cf68

 The Required VBA Code

Next, we need to build our VBA for refreshing the table.  Rather than record and tweak a macro, I’m just going to give you the code that will update all Query Tables in the entire workbook in one shot.  But to use it, you need to know the secret handshake:

  • Press Alt + F11

This will open the Visual Basic editor for you.  If you don’t see a folder tree at the left, then press CTRL+R to make it show up.

  • Find your project in the list (It should be called “»VBA Project (Selecting Data.xlsx)”
  • Right click that name and choose “Insert Module”
  • In the window that pops up, paste in the following code:

Public Sub UpdatePowerQueries()
‘ Macro to update my Power Query script(s)

Dim lTest As Long, cn As WorkbookConnection
On Error Resume Next
For Each cn In ThisWorkbook.Connections
lTest = InStr(1, cn.OLEDBConnection.Connection, «Provider=Microsoft.Mashup.OleDb.1», vbTextCompare)
If Err.Number <> 0 Then
Err.Clear
Exit For
End If
If lTest > 0 Then cn.Refresh
Next cn

End Sub

NOTE:  The code above was updated 2015-08-19 to reflect the method posted here:  https://excelguru.ca/2015/08/19/update-refresh-power-queries-with-vba/

Now, I’ll admit that I find this a little looser than I generally like.  By default, all Power Query scripts create a new connection with the name “Power Query –“ the name of your query.  I’d prefer to check the type of query, but this will work.

Speaking of working, let’s prove it…  But first, close the Visual Basic Editor.

Proving The Refresh Works

The easiest way to do this is to go back to the table on Sheet 1 and add a new row to the table.  I’m going to do that first, then I’m going to:

  • Press Alt + F8
  • Choose “UpdatePowerQueries”
  • Click Run
  • Go back to Sheet2 to verify it’s updated

If all goes well,  you should now have another row of data in your table, as I do:

image

Adding Polish

Let’s face it, that’s probably harder than going to Data –> Refresh All.  The goal here was to make it easier for my users.  So let’s do that now.

  • Return to Sheet 1
  • Go to the Developer Tab (if you don’t see it, right click the ribbon, choose “Customize Ribbon” and check the box next to the Developer tab to expose it)
  • Click Insert and select the button in the top left

image

  • Left click and drag a button onto your worksheet

When you let go, you’ll be prompted to assign a macro.

  • Choose “UpdatePowerQueries” and click OK
  • While the dots are still on the corners, click in the text
  • Backspace it out and replace it with something helpful like “Update Queries” (if you click elsewhere, you’ll need to right click the button to get the selection handles back.)
  • Click in the worksheet to de-select the button

SNAGHTML57873a

That’s it.  Test it again by adding some more data to the table then clicking the button.

Ramifications

I write a lot of VBA to make my users lives easier, and generally use this kind of technique as part of a bigger goal.  But regardless, it can still be useful as a stand alone routine if you want to avoid having to train users on how to do things through the ribbon.

Share:

98 thoughts on “Refresh Power Query With VBA

  1. This is really useful, thanks!

    If i try and refresh my PQ tables with VBA I often (but frustratingly, not always!) get the error that my database is opened by ‘Admin’ on my machine even when the database is closed. I can either try the macro again (sometimes it works) or I can refresh each table manually by right clicking on each one.

    Do you have any idea why this could be happening and what I could do to try and solve it?

    Many thanks,

    Alice

  2. Hi Alice,

    It depends on what kind of database it is. If it’s Access, it could be that another user is in the file and has it locked. Can you share what database you’re trying to connect to?

  3. Great code Ken

    I have several power queries that I will execute usingthis approach. However, I need a mechanism whereby I can lock out the user from interrupting the queries as they are running. When each one refreshes a message in the status bar indicates so but also ‘invites’ the user to ‘ESC to cancel’
    Normally I would use Application.EnableCancelKey = xlDisabled to prevent users breaking into code but this doesn’t seem to work here
    I want to able to indicate to user that queries are refreshing but also stop them from cancelling as it sends them straight into this underlying code

  4. Hi Anthony,

    The issue here is that when you kick off the connection refresh, Excel immediately moves on to the next refresh, and fires it as soon as the previous one is done. With no «AfterConnectionUpdate» event, there’s really no way to set up a trigger to monitor the last refresh, short of using a Wait procedure. That’s obviously not ideal, as we don’t know how long it will take a connection to refresh.

    We could use code similar to the following to disable the cancel key until immediately after the last connection is called:
    Dim cn As WorkbookConnection

    On Error GoTo ErrorExit
    Application.OnKey «{Esc}», «»
    For Each cn In ThisWorkbook.Connections
    If Left(cn, 13) = «Power Query -» Then cn.Refresh
    MsgBox «Refreshed!»
    Next cn

    ErrorExit:
    Application.OnKey «{Esc}»

    I’ll leave it up to you to decide if you want to adjust it to disable the Cancel key until x seconds after the last refresh is kicked off.

  5. Hi Anthony, try this

    Data->Connections->
    Select the connection->Properties
    Uncheck the box «Enable background refresh»

    Regards

  6. Thanks Ken
    I think in this instance it will be a case of ‘this tool will save you 3 hours per day,
    please do not try to break it!’

  7. Hi Ken
    I’ve built quite a large data model which loads up around 40 data files, each transformed using PowerQuery then loaded into data model. If I had to manipulate all of these files by VBA I’d be at it for months. PQ has made a mountainous task possible
    The thing that concerns me is that should any of the data files change in anyway then the respective workbook query will fail. This will be seen by looking in the PQ window. Some data files come from external clients so there is every chance one day some bright spark will decide to add a column. As the PQ is tightly bound to the data source it will just fail
    I have a range of data files and I would like to loop through triggering a refresh on each of them, one by one. I’d like to be able to post a message with success/failure to alert the user that a query has failed due a problem with one of the data files
    There doesn’t appear to be a way of triggering an indivual query refresh then have VBA wait for it to complete before proceeding to the next one
    I can trigger a mass refresh but then you would have to look in the PQ window to check that all of have successfully executed
    Cheers
    Anthony

  8. Apologies, you’ve kind of indicated already that I’m trying to achieve isn’t possible!
    It would be handy if a query could simply post the status you see in the window to a place more visible to user. I.e capture the query success status in VBA somehow

  9. Anthony, if you’re going to pull directly into the model with Power Query, and you’re at all concerned about the stability of the data, I HIGHLY recommend you take a look at Chris Webb’s blog on dealing with data source errors: https://cwebbbi.wordpress.com/2014/09/18/handling-data-source-errors-in-power-query/

    I’d be implementing this right away. Next thing you could do is create a simple measure to COUNTROWS on each table in the Data model, and return them to a cube formula or pivot. This would give you a good indicator if something went wrong. (1 record = bad, more than one = good).

  10. Hi Ken
    Keen to have the core workbook / thin clients arrangement but no PowerPivot server side
    I haven’t checked but I’m wondering whether it is possible to use power query in a different workbook to connect directly into a data model in another?
    If not (and it would be a great additional feature) then my only option is to export some reporting data sets in csv form from my core workbook to be consumed by thin client workbook
    Cheers
    Anthony

  11. Hi Anthony,

    Unfortunately I don’t think that you can connect to the data model in another workbook, no. But you could connect to the same data sources using other workbooks, or even connect to a worksheet from another workbook (allowing you to consume a PivotTable output from a PowerPivot model in that workbook…)

  12. Pingback: Power Query – Controlling M Query Function with User Driven Parameters | Devin Knight

  13. Hi Ken,

    Just wondering if you have extended this into the PowerPivot data model in Excel 2010. Meaning can you update the Data Model in PowerPivot via VBA where the connections are using PowerQuery rather than direct connects to the sq

  14. I used Power Query to pull data from another excel file, transform it and then use the data to build a Dashboard.

    I need to send this dashboard out to 10 leads of 10 different business units with each having just their data every week. Their file should NOT have any other data present at all in the file.

    I’d like to be able to create the 10 different versions and maybe even send the mail out to them on 1 click. I can probably do that by filtering out the data in the table through VBA and refresh the pivots I have in the dashboard.

    Is there a way though using VBA, to tell power query to refresh data for a particular business unit?

  15. Not purely through VBA no, but if you pull in a parameter table, then you can read from Excel cells to dynamically filter the query. That would give you the ability to — via VBA — update the parameter cell, then refresh the query, giving you just that department.

  16. Super helpful thanks!!
    it was useful to help me find issues with my Long Running PowerQueries

    Public Sub UpdatePowerQueries()
    ‘ Macro to update my Power Query script(s)
    Dim TStart As Date
    Dim TEnd As Date

    Dim cn As WorkbookConnection

    For Each cn In ThisWorkbook.Connections
    If Left(cn, 13) = «Power Query -» Then

    Debug.Print cn
    TStart = Now
    cn.Refresh
    TEnd = Now
    Debug.Print CStr(DateDiff(«s», TStart, TEnd)) + » Seconds»
    Debug.Print «»
    Debug.Print «—-«
    End If
    Next cn
    End Sub

  17. Did not work for me. I have a Table called TABLE1 on sheet1 in a workbook. In the same workbook on sheet2 I have a table connected to a power query for TABLE1. I went to sheet1 and added a row and then went back to sheet two and ran this code. Nothing happened. the connection refreshed but the table based off the query did not update. I’m running Excel 2013 with Power Query with all the latest updates. Sigh.

  18. David,

    That’s odd. What module did you put the code in? It should go in a standard module, not a the Sheet2 module…

  19. «Not purely through VBA no, but if you pull in a parameter table, then you can read from Excel cells to dynamically filter the query. That would give you the ability to — via VBA — update the parameter cell, then refresh the query, giving you just that department.» — Didn’t quite understand this, especially the «dynamically filter the query» part. Can you elaborate or point me to any blog post that explains the technique?

  20. Hey there,

    Sure thing. This post illustrates how to build and implement a dynamic parameter table for power query: https://excelguru.ca/2014/11/26/building-a-parameter-table-for-power-query/

    Using the technique described there, you should be able to dynamically control the values used inside power query. Hook some VBA to update the values in the Excel table, then refresh the data and I think you’ve got what you need.

    Hope this helps!

  21. Can this code be modified to run in a protected worksheet? Have tried running an unprotect code, then this code, then another to re-protect the worksheet but it never works for me. Even when adding delays in the code.

  22. Hey Carl,

    My thoughts are that the query is not finished loading before the protection is re-applied. What I’d try is re-protecting the workbook in VBA, but adding this to the end of the line:
    , userinterfaceonly=true

    That should set the protection to protect against users doing something, but still let the macro run.

  23. I am trying to achieve auto-scheduled update, by using Task Scheduler and another Workbook with macros.
    And the problem is — macros alone in the workbook with connections works fine, when I try to run this macros from another workbook by using Application Run and then check works it says «Download did not complete» for each of the query, despite computer was loaded in full, as when I update all manually or with macros in right workbook. Do you have any workaround?

    Macros in Model — workbook with queries:
    Option Explicit

    Public Sub UpdatePowerQueries()
    ‘ Macro to update my Power Query script(s)

    Dim lTest As Long, cn As WorkbookConnection
    On Error Resume Next
    For Each cn In ThisWorkbook.Connections
    lTest = InStr(1, cn.OLEDBConnection.Connection, «Provider=Microsoft.Mashup.OleDb.1»)
    If Err.Number 0 Then
    Err.Clear
    Exit For
    End If
    If lTest > 0 Then cn.Refresh
    Next cn

    Range(«J7»).value = «Updated — » & Date

    End Sub

    Macros in workbook «Macros» — that will be scheduled:
    Option Explicit
    Sub Auto_Open()
    ‘#### To stop the macro you can use keyboard = «ESC» ####’
    Call Main
    End Sub

    Sub Main()
    ‘Disabling some options for better performance during the macro execution’
    Application.Calculation = xlCalculationManual
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False

    Dim strRootFolder As String
    Dim strSearchPath As String
    Dim strSearchName As String

    ‘Setting up the files path’
    strRootFolder = ThisWorkbook.Path & «»
    strSearchPath = strRootFolder & «AP Search Multiyear.xlsm»
    strSearchName = «AP Search Multiyear.xlsm»

    Workbooks.Open strSearchPath
    Workbooks(strSearchName).Activate

    ‘Disabling some options for better performance during the macro execution’
    Application.Calculation = xlCalculationManual
    Application.ScreenUpdating = False
    Application.DisplayAlerts = False

    » Macro to update my Power Query script(s)
    Application.Run («‘» & strSearchName & «‘!UpdatePowerQueries»)

    »https://excelguru.ca/2014/10/22/refresh-power-query-with-vba/
    ‘Screen update
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True

    ActiveSheet.PivotTables(«PivotTable1»).PivotCache.Refresh
    Workbooks(strSearchName).Save

    ‘SAVE AND CLOSE EXCEL PHASE’
    Workbooks(strSearchName).Close False

    ThisWorkbook.Activate
    ThisWorkbook.Save
    Application.Quit

    End Sub

  24. Alex, I think I’d probably lean to Power Update to solve this issue, to be honest…

  25. Hi everyone!

    First of all, thanks Ken for your article… piece of cake 😉

    I have a similar code than Alex, the same issue and (sadly) the same result when the queries are updated automatically by a macro («Download did not complete»), but they are successfully updated if the process is run manually.

    I have tried some ways to solve this issue as:

    — Including the sentence «DoEvents» after the update process in the macro.
    — Updating each connection in a loop instead of using «RefreshAll».
    — Using the sentence Application.Wait(«Time») after the update process with a several amount of seconds.

    I know (as you said Ken) Power Query doesn´t provide any VBA object model but, is there any way to retrieve the status of a query of Power Query?

    I have been thinking that if we can get the status, we can repeat the update process until the data download is complete.

    Thanks in advance.

  26. Unfortunately, not that I’m aware of, no. The thing is that in Excel 2013 we’re not actually refreshing Power Query. We’re actually refreshing the Excel connection, which happens to kick off Power Query. Being that Power Query is an addin, there is no flag that gets pushed back to Excel to say «I’m done».

    My feeling is that the only method we have to attempt to insert control here is to possibly flip the setting on the connection to turn off background refresh. My hypothesis here is that it SHOULD prevent Excel from moving on before refreshing the subsequent connections, but I could be wrong there. I haven’t had time to fool around with it and come up with a reliable solution, unfortunately.

  27. @Alex, does this work?

    If lTest > 0 Then
    cn.BackgroundQuery = False
    cn.Refresh
    End If

    Regards

  28. Sorry, I solved the problem, but forget to point it to you.
    I added some lines, than enable refresh (by default disabled and after macros as well) and wait until queries done:
    On Error GoTo ErrorExit
    Application.OnKey «{Esc}», «»
    For Each cn In ThisWorkbook.Connections
    If Left(cn, 13) = «Power Query -» Then cn.EnableRefresh = True
    cn.Refresh
    Application.CalculateUntilAsyncQueriesDone
    Next cn

    Application.CalculateFullRebuild
    Application.CalculateUntilAsyncQueriesDone

    ‘Application.ScreenUpdating = True
    For Each cn In ThisWorkbook.Connections
    If Left(cn, 13) = «Power Query -» Then cn.EnableRefresh = False
    Next cn

  29. Cool Alex. Thanks for posting back on this!

  30. @Alex I’ve run into the same issue and implemented the solution you provided but still receive the same results (i.e. «Download did not complete.»). My code is below; do you see any issues?

    For Each cn In TDR.Connections
    If Left(cn, 13) = «Power Query -» Then cn.EnableRefresh = True
    cn.Refresh
    Application.CalculateUntilAsyncQueriesDone
    Next cn

    Application.CalculateFullRebuild
    Application.CalculateUntilAsyncQueriesDone

    ‘Application.ScreenUpdating = True
    For Each cn In TDR.Connections
    If Left(cn, 13) = «Power Query -» Then cn.EnableRefresh = False
    Next cn

  31. Is it important which query got refreshed first in your VBA loop if we have a chain of dependent queries? (E.g. Q3 is merge of Q1 and Q2 ,Q6 is Q5 append Q4 and then Q7 is merge of Q3 and Q6)

  32. Hi Leonid,

    To be honest, after learning a bit more about this approach I think I’d actually just automate the Data —> Refresh All process wherever possible. At that point the query sequencing will take care of itself, and you’ll also find that it performs better, especially if you have a larger number of queries. (We have discovered that the data model gets cached after each refresh operation, so if you run the macro above it would refresh and cache 7 times vs doing the cache only once with the data —> refresh all approach.)

  33. Not sure if others faced this issue but just updated Power Query and the Connection String of my Power Query tables changed to: provider=Microsoft.Mashup.OleDb.1

    Note the lowercase «provider» which you’ll have to edit in the VBA code to compensate for this.

  34. Well that’s more than a bit frustrating, isn’t it? I’m curious, did this change for existing connections or just new ones?

    We can pretty easily fix this by modifying the lTest line as follows:

    lTest = InStr(1, LCase(cn.OLEDBConnection.Connection), «provider=microsoft.mashup.oledb.1»)

    But we really shouldn’t need to do this…

  35. Hey Matt,

    I just checked this, and I can’t repro what you’re seeing here. I just created a brand new Power Query using Excel 2016 (the very latest insider build), and it’s working as expected, returning an upper case «P» for provider…

  36. Just troubleshooted the issue and believe I figured out the cause…

    I had created a file in which I used Power Query in Excel 2010. I then opened this file in Excel 2013. For whatever reason this permanently changes the existing connection’s string from uppercase to lowercase «provider»

    I edited your VBA code (removing «provider» altogether) to make sure I never face this issue again:
    InStr(1, cn.OLEDBConnection.Connection, «Microsoft.Mashup.OleDb.1»)

    Do you foresee any issues with me doing this?

  37. I don’t foresee issues doing that, no. Interesting find re 2013. I’ll have to look into that.

  38. I have text file with 2 million data I need to import to excel by power query.. before doing this there are 5 columns which 2 columns are dependent . how can I import only 5 columns and get distinct values from that columns…. the table has duplicate rows. and there is no unique row to identify. then user will be given drop down list. the list will be populated by unique rows from those 5 columns and user can select the values from the list and extract the data….. Note: those 5 columns will be there in the text file.

  39. Hi Ken,

    Thank you for this article. It had been working refreshing the data. However, today it won’t refresh at all. My process is I run the refresh, copy the result into another worksheet, and hide that worksheet. I made this dynamic date range. So if I enter a new date range and hit refresh, it should pull in new data. The date range with the refresh button is in another worksheet. When the refresh button is pressed, it will unhide the worksheet that has is used for the Power Query.

    Now, it won’t refresh anymore when I hit the refresh button. I used the code that you provided. I just don’t know what I did wrong or what happened.

    I am wondering if you know if I changed something within the spreadsheet without me knowing it? I updated to the new Power Query add-in.

    Thank you!

  40. James, did a workbook that has been working suddenly start failing, or did the method start failing when you applied it to a new workbook?

    I did just modify the VBA in the post a bit to add the «, vbTextCompare» to the end of the lTest line (inside the closing parenthesis). This should fix an issue if the case of the connection string changes. Beyond that, I’m not sure what would cause this, as we’re not referring to any query names here.

    What version of Excel are you using here?

  41. Ken,
    Very good article. I used the macro in my VBA routine to refresh my tables. I am having a problem though that you may be able to help me with. After adding the routine and storing the file, upon reopening it, I get an error, saying that it is unable to create an ActiveX control. As it is, the file is lost to me. Do you know how to fix this?

  42. Hey Don,

    Honestly, no… the code I use in the article above doesn’t reference an ActiveX control in any way. It’s probably related to the button you used to trigger it, or some other control, but can’t be certain without more info. This may be a good question to post in the forum at http://www.excelguru.ca/forums as there is something else going on here.

  43. Ken,
    I fixed the problem which was to re-load the Power Query add-in. It’s working fine for the moment. I tried to load another workbook with tables and got the same error after I hit «enter» which told me it was the Power Query and not the sources. I figure the Active X control is found in Power Query itself, not the code. Thanks anyway for the help.

  44. Update:
    There is a conflict with Skype where some subroutine will not work. I need to not update Skype in order to make Power Query work. Otherwise I need to repair it first. I don’t know if anyone else has this problem but this may help.

  45. Now that is odd, and should not happen. I’m also curious if anyone else experiences this.

  46. Hi Ken,

    Just one question: would it possible to run a macro from another worksheet? I need to refresh several querys from a main worksheet to rule all the process.

    Thanks in advance.

  47. Sure. If you link the macro to a button, it doesn’t matter which sheet the button lives on. I’ve built many solutions where there is a single sheet with multiple buttons to control the execution of each macro when needed.

  48. Hello,
    It realy useful. Thanks.
    Another issue with which i fighting.
    I’m working on few PC. So, I have problem with datesource for PQ.
    Maybe You have some solution how to change source automatically in PQ with VBA?

  49. Not with VBA in Power Query, no. VBA works outside Power Query.

    For dates the most likely thing you need to do is use change type -> using Locale to set it to the format of the source data. That will override your system settings.

  50. Hi, trying to find a solution to update the source string in Power query based on data entered in specific cell in my workbook on a separate tab. Do you have any ideas how to do this?

  51. Hey Ken,

    I’ve been looking all over the excel forums but there’s nothing so far.
    I need to refresh a Power Map using a macro instead of the button itself so it would be like a real-time visualization of my data that is being imported from another source every 30sec.
    Do you think it is possible?

  52. Hi is there any chance to get message popup upon query is loaded? thanks

  53. I used your macro and it works. However, I’m trying to have the macro auto execute before closing the file. In other words, when the user saves the file and then clicks to close the file, before it actually close I want the macro to execute and save the file without any more intervention from the user. Come to think of it, it might be better if the macro execute on saving and not on close.

    Here how the code looks like now:
    Private Sub Workbook_UpdatePowerQueries()
    ‘ Macro to update my Power Query script(s)

    Dim lTest As Long, cn As WorkbookConnection
    On Error Resume Next
    For Each cn In ThisWorkbook.Connections
    lTest = InStr(1, cn.OLEDBConnection.Connection, «Provider=Microsoft.Mashup.OleDb.1», vbTextCompare)
    If Err.Number 0 Then
    Err.Clear
    Exit For
    End If
    If lTest > 0 Then cn.Refresh
    Next cn

    End Sub
    At this point the macro executes but it pops up a window warning that closing the file will cancel the query. Help!

  54. Hey Joao, I’m not sure that we can automate Power Map via VBA. Nothing comes up in the macro recorder, but to be fair I haven’t dug into the object model too deeply.

  55. Hi Zuna,

    I believe you need to set the query to run as a background query, which will force it to load before moving on, then you could put a msgbox at the end. Something like this:

    Set cn = wb.Connections(«Query — Name»)
    With cn
    .OLEDBConnection.BackgroundQuery = False
    .Refresh
    .OLEDBConnection.BackgroundQuery = True
    End With
    MsgBox «Complete!»

  56. Ariel, try this version instead:

    Private Sub Workbook_UpdatePowerQueries()
    ‘ Macro to update my Power Query script(s)

    Dim lTest As Long, cn As WorkbookConnection
    On Error Resume Next
    For Each cn In ThisWorkbook.Connections
    lTest = InStr(1, cn.OLEDBConnection.Connection, «Provider=Microsoft.Mashup.OleDb.1», vbTextCompare)
    If Err.Number 0 Then
    Err.Clear
    Exit For
    End If
    If lTest > 0 Then
    cn.OLEDBConnection.BackgroundQuery = False
    cn.Refresh
    cn.OLEDBConnection.BackgroundQuery = True
    End If
    Next cn

    End Sub

  57. Ken, I tried the new version and it does not work. I get a popup window asking me if I want to save my changes, I click yes and it saves and closes the file. But when I open it again, the table is not refreshed.
    I know next to nothing about coding so I apologize. Do you know what might be malfunctioning here?

  58. To be honest, this would probably be better served in our help forum at http://www.excelguru.ca/forums. You can upload a workbook so we can test and see what may be the root cause.

  59. Ken, never mind I think I know what happed. My PowerPivot addin was disabled. Sorry.

  60. Ken, just to let you know that it works like a charm. Thank you!

  61. In Excel Power Query, one can group multple queries into a folder or group. Is there a VBA code that can specify to refresh the group of queries using the Group folder name?

  62. Sorry Todd, there’s not. I wish there was. Power Query groups and folders are invisible to VBA. 🙁

  63. Ken, How do you tell a macro to wait until the PQ query is complete before refreshing a pivot table? In my code below, the PT refreshed BEFORE the PQ is rereshed.

    With ThisWorkbook
    Set ptFees = shtptFees.PivotTables(«PTFees»)
    .Connections(«Query — tblProducers»).Refresh
    ptFees.PivotCache.Refresh
    End With

  64. Hi Mike,

    Try this and see if it helps:

    Set ptFees = shtptFees.PivotTables("PTFees")
    Set cn = ThisWorkbook.Connections("Query - tblProducers")

    With cn
    .OLEDBConnection.BackgroundQuery = False
    .Refresh
    .OLEDBConnection.BackgroundQuery = True
    End With

    ptFees.PivotCache.Refresh

  65. AWESOME…Thank you!

  66. Excellent, worked from the first try,

    Thank you Ken, you are awesome and help was just on time!

    Have a great day
    Anna

  67. Hi, Ken! I remember I once saw a post from you somewhere about the VBA code to define the order in which we want Queries to refresh. Can’t find it. Would you by chance know where that solution could have been posted?

  68. Hi Celia, I honestly can’t remember either, but…

    By default, Queries with load destinations refresh in alphabetical order (refreshing any child queries along the way.) If you need to use VBA to refresh them in a specific order, then I’d just record a macro to refresh one, then copy the line of code and tweak it for the other queries.

  69. Hi Ken,

    In order to avoid the inexplicable glitches that can occur when refreshing queries with VBA (inexplicable to me anyway), my approach (in 2016) has been to create queries with VBA to generate the results then delete all queries at the end of the process. In other words, my practice is to delete all queries from the workbook before closing and then recreate them with VBA either on user-demand or automatically when the workbook is opened again.

    I never figured out what caused the intermittent, seemingly random errors with the VBA-driven refresh…I just know that moving to the deletion/recreation technique solved that problem for me in every case.

    Our enterprise is a mix of 2013 and 2016. I’m trying to develop a Power Query solution that works in both environments, detecting the version and then running different code based on the version. The problem is that I can’t figure out how to apply the delete/create technique in 2013. Again, I don’t want to leave queries in the workbook to be refreshed by VBA as I’ve had so much trouble with that in the past. Is there any way to apply the delete/recreate technique in 2013?

  70. Hi Michael,

    I’ll be honest, I’ve never had any glitches when using VBA to refresh queries. I build solutions frequently to do exactly this, link it to a button for end users and then have a way to control which queries get refreshed, and in what order if that is an issue. I’m curious why you’re having issues, as that isn’t normal.

    With regards to 2013, the issue you have is that Power Query is an add-in, so there is no object model to delete or create queries. Refresh is different, as a macro can be recorded to refresh the data connection.

  71. I’ve been meaning to post this for a while, but, you know…
    Based on the work posted by Ken and others, I built a function to update a query by its name. It has worked in Excel 2010 and Excel 365 very reliably for queries to Excel, CSV, SQL and Access, as well as internal queries from tables in the same excel file.

    The «QueryName» value in the calling function is the natural Power Query name of the query.
    Hope that this helps anyone struggling with VBA updates for Power Query.

    Calling function:
    ….
    Dim Result as string
    Result = updatePQ(«QueryName»)
    If Result Like «*Error*» Then Err.Raise (1001) ‘calls error handler
    ….

    Update Function:
    Option Explicit
    Function updatePQ(nmQuery As String) As String
    Dim qName As String
    Dim ix As Long
    Const qPrefix As String = «Query — «

    On Error GoTo Err01
    ix = InStr(nmQuery, qPrefix)
    qName = nmQuery
    If ix < 1 Then qName = qPrefix & nmQuery

    With ActiveWorkbook.Connections(qName).OLEDBConnection
    .BackgroundQuery = False
    .MaintainConnection = False
    .Refresh
    End With
    updatePQ = «OK»
    XIT:
    Exit Function
    Err01:
    updatePQ = «Error — PQ Refresh: » & nmQuery
    Resume XIT
    Resume
    End Function

  72. It appears that if your query is added to the Data model in Excel, that the VBA code will «wait» until the query completes before executing the next line of vba code. Can anyone else confirm this?

  73. Hi Mike,

    I just did a VERY quick test on this, and from what I can see, yes. The code waits for the model to complete it’s operations before executing the next line of code.

  74. Hi Ken , Thanks a lot finally I find the macro code that helps me to refresh the power Query. Just now I need your help what is the code of macro after refresh power query refresh pivot table

  75. Hi Pegah,

    If you turn on the macro recorder, you can right click your Pivot Table choose Refresh, and you’ll have the code. You may also want to just record a macro to do the Data -> Refresh All action as that will refresh the queries and all PivotTables.

  76. Thanks Ken. I write this code the end of your code but I must run the macro tow times then the pivot table will be updated. would you please guide me which part is wrong.
    Sub Run()

    ‘ Run Macro

    Dim lTest As Long, cn As WorkbookConnection, pt As pivotTable
    On Error Resume Next
    For Each cn In ThisWorkbook.Connections
    lTest = InStr(1, cn.OLEDBConnection.Connection, «Provider=Microsoft.Mashup.OleDb.1», vbTextCompare)
    If Err.Number 0 Then
    Err.Clear
    Exit For
    End If
    If lTest > 0 Then cn.Refresh

    Next cn
    For Each pt In ActiveSheet.PivotTables

    Select Case pt.Name

    Case «PivotTable1»

    pt.RefreshTable

    Case Else

    End Select

    Next pt
    End Sub

  77. Hi Pegah,

    Try updating your lTest/next cn lines with the following:

    If lTest > 0 Then
    cn.OLEDBConnection.BackgroundQuery = False
    cn.Refresh
    cn.OLEDBConnection.BackgroundQuery = True
    End If

  78. Hi Ken,
    Thanks but it doesn’t work again

  79. Hi Ken,
    I’m having the same problem as Pegah in needing to run my VBA code twice to achieve the result I am expecting. Adding BackgroundQuery statements as follows:
    With cn
    .OLEDBConnection.BackgroundQuery = False
    DoEvents
    .Refresh
    DoEvents
    .OLEDBConnection.BackgroundQuery = True
    End With

    is not successful in forcing the table to be updated in time for the next VBA steps which use the information from the table. The result after the VBA code completes is that the PowerQuery has updated its table correctly, but the subsequent tables that are populated from the query data are missing information, because it was updated too late for the next step.

    I have tried DoEvents and Application.Wait Now + TimeValue(«00:00:ss»), but these merely slow the process without achieving the desired result. I’ve also tried creating a new sub to run the code twice, but this falls over at the second running of .OLEDBConnection.BackgroundQuery = False with an Error 1004 «Microsoft Excel is refreshing some data. Please try again later»

    It’s very hard to debug this problem, because the mere fact of pausing while stepping through means that I never encounter an error because the query catches up.

    I’d really appreciate your thoughts, please.

  80. Geoff & Pegah,

    If you scroll up the comments to Jan 11 2016, Alex posted a solution that has some extra components in it about calculating AsyncQueries and a FullRebuild. Can you see if slotting some of those in fixes the issue?

  81. Thanks, Ken, that worked a treat

  82. Hi Ken,
    Is there a way to have a secondary query refresh when a cell from the primary query is clicked on? Example, if I click on the word ‘Cat’, I would like it pass that as a parameter to my secondary query to retrieve additional details into a separate worksheet. I should note I already have a parameter table for my primary worksheet and there’s no desire to that the primary refresh automatically.

    Any ideas would be greatly appreciated.
    Thanks

  83. Hi Christine,
    The only way I can think of that you could do this would be with VBA’s Worksheet_SelectionChange event. You’d want to set up a query specifically for this, then use the event to update the query, then refresh it. No idea how performant it would be, but I think it would work.

  84. To add my two cents, I would do exactly what Ken suggests, with the caveat that I would read the table back into PQ from the sheet as the source for the secondary query rather than using the primary query as a direct source, since that would cause the primary query to refresh first.

  85. Hi Ken and AlexJ,
    Yes, the secondary query is not sourced from the primary query. I would just like to use a value from the primary query as a parameter value to call the secondary query. Does this change your suggestion?

  86. Hi Christie,

    If you go the VBA route, it would work. Each query (in Excel 2016 and higher) has a .Formula property which contains the M code for the Power Query. (What you see in Power Query’s advanced editor.) If the SelectionChange event were to update the query’s .Formula to a new M code formula, then refresh it, that should do the trick.

  87. Hi Ken —

    Thanks so much for this tip, it is very helpful. QQ though — how do we know that the power queries are refreshed in the right order? For example, if Query 3 has dependency on Query 2, and 2 on Query 1, we want them refreshed in the correct order. As per your code above, it seems to just refresh them in a random order. Please let me know if i am missing something. Thanks!

  88. Hi Sid,

    If you refresh Query 3, it will automatically refresh the child objects Query 1 and Query 2, and there is no way to disable that. Assume though, that you wanted to refresh Query1, land it to a table, then add some info to another column. Then you wanted to merge that table with Query 2, you would want to refresh Query1 out of sync, so it would make sense to do this.

    With regards to the query chain, barring dependencies, it refreshes in alpha order I believe. There is no dependency information available via the VBA object model, but if you want an easy way to get it, consider trying https://excelguru.ca/monkeytools as we do provide that in the QuerySleuth form.

  89. Hi Ken,

    I want to refresh connections only queries (power queries) using vba and read the record count from the connection. If record count is more than 0, I want to publish result in separate worksheet. Not sure, if this is possible. please advise
    On another note : do you know what is best way to get only results where record count is more than 0 in excel in place of having all the sql linked to separate worksheet for results.

  90. Hi Amit,

    Unfortunately, the only way to get a row count is to do the full refresh and then read it from the resulting table. We have no ability to read the previews (which aren’t full data sets anyway.)

  91. im stomped i have a workbook where if i update queries manually they update fine and within a minute each. But if i use update all, they never finish. Any ideas?

  92. Ken,
    I use a button and apply the following code and it refreshes all queries in the workbook. What would be the advantage of your code over what I am currently using.

    Sub Macro4()
    ActiveWorkbook.RefreshAll
    End Sub

    Alan

  93. Hi Ken,

    Would you please confirm for me that the Sub Run() macro from Aug 19, 2015 runs all queries in the order of query dependencies — similar to how Refresh All would work?

    I have a number of queries that are dependent on outputs from other queries, and am trying to determine whether this script would be useful for including in a For loop to update across multiple states.

    I am able to run this script in the For loop flawlessly, but once again, am just looking for confirmation that the refreshing of all queries runs in the order associated with query dependencies.

    Thank you,

    Geo

  94. Hi Geo,

    No… the native Power Query object model has zero idea of any dependencies. This code allows refreshing queries in the order they appear in the queries pane. If multiple queries share children, those child queries will get refreshed as each parent is updated. If you want to have all queries refresh while observing the proper dependency chain, then you should use the code that Alan posted immediately above.

    The reason you’d use this code is to force queries to update in the specified order, despite the fact that it may actually be slower to do so.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Latest Posts

Excel Fundamentals Boot Camp

COACHED TRAINING: Excel Fundamentals Boot Camp Course Description In the Fundamentals Boot Camp, you will begin with a review core skills for the Excel analyst. This section is geared to

Read More »


October 06, 2020/



Chris Newman

Refresh Excel Data Connections VBA

With the release of integrated stock pricing in Microsoft Excel, it was unfortunate there wasn’t any sort of setting that allowed for automatic updating of the stock data while the file was open.

Even worse, there is currently no way to ensure the data refreshes when you initially open your Excel file. This becomes vitally important if you are relying on your stock data to be up-to-date before making any trading decisions.

Let’s look at a few ways we can incorporate VBA code to help remedy the lack of this feature.

In this article, I’ll cover how to:

  • Refresh your query data manually

  • Refresh your data automatically when the file opens

  • Refresh your data automatically when you select a specific tab

  • Refresh your data at a given interval (ie every 30 seconds)

Refresh Data Connections Manually

You can trigger the refreshing of your stock data by either using keyboard shortcut Ctrl+Alt+F5 or navigating to your Excel Ribbon’s Data tab and clicking the Refresh All button within the Queries & Connections button group.

Refresh All Button.png

Refresh Data Connections When File Opens (VBA)

You can trigger a data refresh when your Excel file is first opened by pasting VBA code into the Workbook_Open event. Simply double-click the ThisWorkbook object in the VBA Project Pane to open the text editor (blank white sheet) within the Visual Basic Editor (keyboard shortcut Alt +F11).

Next, paste the below code into the text editor and save.

Private Sub Workbook_Open()
‘PURPOSE: Run Data tab’s Refresh All function when file is opened

ThisWorkbook.RefreshAll

MsgBox «Stock Data has been refreshed!»

End Sub

Workbook Event.png

The next time you open your Excel file, you should see the message box immediately appear indicating that your stock data has been refreshed.

Refresh Data Connections When Sheet Is Activated (VBA)

You can trigger a data refresh when you navigate to a particular spreadsheet tab by pasting VBA code into the Worksheet_Activate event. Simply double-click the desired Sheet object in the VBA Project Pane to open the text editor (blank white sheet) within the Visual Basic Editor (keyboard shortcut Alt +F11). The tab name of your sheets will be inside the parathesis next to the object name, so you can easily decipher which sheet object you want to store the code in.

Next, paste the below code into the text editor and save.

Private Sub Worksheet_Activate()
‘PURPOSE: Run Data tab’s Refresh All function when sheet is activated

ThisWorkbook.RefreshAll

MsgBox «Stock Data has been refreshed!»

End Sub

Worksheet Event.png

The next time you navigate to the particular tab you stored the code in, you should see the message box immediately appear indicating that your stock data has been refreshed.

Refresh Data Connections Every X Seconds (VBA)

Alright, this is for all the day traders out there that want their data automatically refreshed throughout the day. We can utilize VBA’s OnTime functionality to schedule a macro to run and effectively create a loop so that it keeps refreshing at your desired interval.

There are 4 macros in the below code, however, you will only need to call two of them:

  1. StartRefreshLoop — Starts the refresh intervals

  2. EndRefreshLoop — Ends the refresh intervals

You can set the public variable “Seconds” to any interval you wish. Since stock data typically refreshes every 15 minutes, you’ll most likely want to set it to 960 seconds.

Public RefreshTime As Double
Public Const Seconds = 30 ‘Input Refresh Interval in seconds

Sub StartRefreshLoop()

‘User Message indicating loop is beginning
  MsgBox «Refreshes will begin to occur at » & _
    «the designated interval of » & Seconds & » seconds»

‘Call the first Refresh
  Call StartRefreshes

End Sub

Sub StartRefreshes()

‘Calculate Next Refresh Time
  RefreshTime = Now + TimeSerial(0, 0, Seconds)

‘Trigger a Refresh with OnTime function
  Application.OnTime _
    EarliestTime:=RefreshTime, _
    Procedure:=»RefreshConnections», _
    Schedule:=True

  End Sub

Sub RefreshConnections()

‘Refresh Data Connections
  ThisWorkbook.RefreshAll

‘Start Timer Over Again
  Call StartRefreshes

End Sub

Sub EndRefreshLoop()

‘On Error Resume Next
  Application.OnTime _
    EarliestTime:=RefreshTime, _
    Procedure:=»RefreshConnections», _
    Schedule:=False

‘User Message indicating loop has ended
  MsgBox «Refreshes are no longer occurring»

End Sub

I Hope This Helped!

Hopefully, I was able to explain how you can use VBA code to automate refreshing your data connections to ensure you have the most up-to-date stock information in your spreadsheets. If you have any questions about this technique or suggestions on how to improve it, please let me know in the comments section below.

Chris Newman 2020 - TheSpreadsheetGuru

About The Author

Hey there! I’m Chris and I run TheSpreadsheetGuru website in my spare time. By day, I’m actually a finance professional who relies on Microsoft Excel quite heavily in the corporate world. I love taking the things I learn in the “real world” and sharing them with everyone here on this site so that you too can become a spreadsheet guru at your company.

Through my years in the corporate world, I’ve been able to pick up on opportunities to make working with Excel better and have built a variety of Excel add-ins, from inserting tickmark symbols to automating copy/pasting from Excel to PowerPoint. If you’d like to keep up to date with the latest Excel news and directly get emailed the most meaningful Excel tips I’ve learned over the years, you can sign up for my free newsletters. I hope I was able to provide you some value today and hope to see you back here soon! — Chris

Понравилась статья? Поделить с друзьями:
  • Excel vba обновить все подключения
  • Excel vba массивы данных
  • Excel vba массивы variant
  • Excel vba массив удалить дубликаты
  • Excel vba массив строковый