2015-02-08 1 views
-1

У меня есть рабочий лист, который получает данные от сервера ДРВ по следующей формуле:Pause сервер ДРВ в Excel и сохранить таблицу

=RTD("tos.rtd", , "ASK", ".SPX150220C750") 

Я хотел бы сохранить таблицу с приведенной выше формулой раз в 1 минуту или около того. Задача состоит в том, чтобы приостановить код VBA, а также убедиться, что перед сохранением значение в ячейке обновляется. Я пробовал следующий код.

Sub Archiving() 
For i = 0 To 4 

    Worksheets("Test").Activate 
    Application.Sheets("Test").Copy 
    Application.DisplayAlerts = False 
    ActiveWorkbook.SaveAs Filename:="D:\Save " & i & ".csv", FileFormat:=xlCSV 
    ActiveWorkbook.Save 
    ActiveWindow.Close 
    Windows("Real time data.xlsm").Activate 
    Application.DisplayAlerts = True 

    Application.Wait (Now + TimeValue("0:00:05")) 

    ActiveWorkbook.RefreshAll 
    DoEvents 
Next i 

End Sub 

код не работает, просто потому, что DoEvents ждет, пока RTD не будет сделано с обновлениями, которые никогда. Я также видел пример, когда соединение с БД приостанавливается явно, но я не знаю, как адаптировать его к серверу RTD. Я попытался запустить RTD-сервер с C#, но неудачно провалился. RTD in C# for dummies Любые предложения?

+0

Я не знаком с RTD, но вы пытались использовать функцию WinAPI 'Sleep'? Это должно привести к тому, что приложение Excel будет «спящим» на определенный интервал. Экономия каждые 1 минуту кажется излишне налогооблагаемой, нет? Является ли приложение настолько неустойчивым, что более длинный интервал не подходит? –

+0

Спасибо, Дэвид. Думаю, я уже пробовал «Сон». Проблема в том, что Excel не получает полностью обновить рабочий лист, Excel сохраняет старые данные. Я могу увеличить интервал сохранения до 5 минут, но моя цель - собрать данные в режиме реального времени, поэтому я бы хотел, чтобы временной интервал сохранения был настолько малым, насколько это технически возможно. – user1700890

+0

Мне все еще интересно, почему вы чувствуете необходимость * сохранять * документ так часто ... вы создаете новую копию файла в каждой точке сохранения? Если это так, это ужасно избыточно, не так ли? И если нет, каждая операция «save» перезаписывает предыдущее сохранение, поэтому почему бы не использовать менее интенсивный интервал или зачем вообще его автоматически сохранять? Предполагая, что ваше приложение стабильно и не случайно «сбой», нет реального риска потери данных ... –

ответ

1

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

ПРОБЛЕМА с предыдущей реализации является то, что, делая это внутри цикла, поскольку VBA не поддерживает многопоточность, приложение было «занято» и не в состоянии получить новые данные от сервера ДРВ.

Это основано главным образом на том, что я собрал из Microsoft, documentation/knowledge-base, подчеркивание добавлено:

Функция RTD извлекает данные из сервера ДРВ для использования в книге. Результат функции обновляется всякий раз, когда новые данные становятся доступны с сервера и рабочая тетрадь может принять его. Сервер ждет, пока Excel не будет обновлен до обновления. Это освобождает разработчика от необходимости определять, доступен ли Excel для принятия обновлений. Функция RTD отличается от других функций в этом отношении, потому что другие функции обновляются, только когда рабочий лист пересчитывается.

И далее говорит, что переключая приложения .CalculationState и т.д. не будет иметь никакого влияния на сервере RTD:

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

Таким образом, данные будут обновляться, когда он становится доступным с сервера (предположительно не проблема), но то, что проблема в вашей реализации является то, что книга не может принять его, потому что он работает нить VBA и Формула RTD не является «нормальной» внешней ссылкой.

Хотя функция RTD обеспечивает связь с данными на сервере, то не тот же тип ссылки как ссылки на ячейки в других рабочих листах или книг.Например, если вы используете функцию RTD в рабочей книге, , вы не получаете сообщение о запуске ссылок при открытии книги , а также не можете управлять статусом функции RTD через диалоговое окно «Редактировать ссылки» .

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

ПОТЕНЦИАЛ РЕШЕНИЕ

Используя Application.OnTime событие для планирования сохранения интервала, я думаю, вы должны быть в состоянии избежать проблем книги будучи не в состоянии получить данные.

если вы хотите СОХРАНИТЬ данных через регулярные промежутки времени, то эта функция будет вызывать саму себя рекурсивно, при условии соблюдения ограничений Appliction.OnTime method:

Private Sub CreateArchive() 
    'Saves a copy of sheet "Test" and sets OnTime to save again in 60 seconds 
    Dim saveTime as String 

    saveTime = Format(Now(), "YYYY-MM-DD-hh-nn") 

    Worksheets("Test").Copy 
    Application.DisplayAlerts = False 
    ActiveWorkbook.SaveAs Filename:="D:\Save " & saveTime & ".csv", FileFormat:=xlCSV 
    ActiveWorkbook.Close 
    Windows("Real time data.xlsm").Activate 
    Application.DisplayAlerts = True 

    'Call on this function again in 60 seconds: 
    Application.OnTime Now + TimeValue("00:00:60"), CreateArchive 

End Sub 

Примечание: Я не могу копируют на мой конец, потому что у меня нет вашего COM-объекта/etc. который вызывается из функции RTD. Итак, возьмите это с солью и поймите, что я очень ограничен в том, какую дальнейшую помощь я могу вам предложить.

+0

Ты лучший, Дэвид! Ваш метод работал! Благодаря тонну! – user1700890