Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Программирование, связанное с MS Office > Периодический запуск UDF


Автор: Pogreb 5.2.2008, 00:36
Доброго времени суток =)

У меня такая проблема, написана пользовательская функция (UDF), ее надо запускать периодически, чтобы она пересчитывала значения в ячейках таблицы. На форуме нашел ссылки только на автоматический запуск или по расписаню макросов, но это не совсем макрос.

Как быть и что делать?

Спасибо.

Вот код функции:

Код


Function GetQuote(strTicker As String)
    On Error Resume Next
    
    Const intMaxErrCount = 5
    
    Dim xmlHttpDoc
    Dim strSourceUrl As String, strInput As String
    Dim intStartPosn As Long, intEndPosn As Long
    Dim intErrorCount As Long
    Dim blnError As Boolean
    Dim strErrMsg As String
    Dim dblQuote As Double

    

    blnError = True
    intErrorCount = 0
    strTicker = UCase(Trim(strTicker))
    
    'http://moneycentral.msn.com/scripts/webquote.dll?iPage=qdext&Symbol=CIOBX

    strSourceUrl = "http://moneycentral.msn.com/scripts/webquote.dll?iPage=qdext&Symbol="
    strSourceUrl = strSourceUrl & strTicker
    
    While intErrorCount <= intMaxErrCount And blnError
        Set xmlHttpDoc = CreateObject("MSXML2.XMLHTTP")
        blnError = False
        xmlHttpDoc.Open "GET", strSourceUrl, False
        xmlHttpDoc.Send
        strInput = xmlHttpDoc.responseText
        If Err.Number <> 0 Then
            strErrMsg = "Error connecting for " & strTicker & "."
            blnError = True
            intErrorCount = intErrorCount + 1
            wscript.sleep (intErrorCount * 1000)
            Err.Clear
        Else
            ' Parse Response
            If InStr(strInput, "Net Asset Value") Then
                ' It's a Fund
                ' Get the current quote
                dblQuote = 0
                intStartPosn = InStr(strInput, "Net Asset Value")
                intStartPosn = InStr(intStartPosn, strInput, "<B>&nbsp;") + 9
                intEndPosn = InStr(intStartPosn, strInput, "</B>")
                dblQuote = CDbl(Mid(strInput, intStartPosn, intEndPosn - intStartPosn))
                strErrMsg = ""
                If Err.Number <> 0 Then
                    strErrMsg = "Error parsing for " & strTicker & "."
                    blnError = True
                    intErrorCount = intMaxErrCount
                    Err.Clear
                End If
            ElseIf InStr(strInput, "<TD>Last</TD>") Then
                ' It's a Stock or Index
                ' Get the current quote
                dblQuote = 0
                intStartPosn = InStr(strInput, "Last")
                intStartPosn = InStr(intStartPosn, strInput, "<B>&nbsp;") + 9
                intEndPosn = InStr(intStartPosn, strInput, "</B>")
                dblQuote = CDbl(Mid(strInput, intStartPosn, intEndPosn - intStartPosn))
                strErrMsg = ""
                If Err.Number <> 0 Then
                    strErrMsg = "Error parsing for " & strTicker & "."
                    blnError = True
                    intErrorCount = intMaxErrCount
                    Err.Clear
                End If
                 ElseIf InStr(strInput, "<tr class=""rs0""><th colspan=""4""><span class=""s1"">") Then
                dblQuote = 0
                intStartPosn = InStr(strInput, "<tr class=""rs0""><th colspan=""4""><span class=""s1"">") + 49
                intEndPosn = InStr(intStartPosn, strInput, "</span>")
                dblQuote = CDbl(Replace(Mid(strInput, intStartPosn, intEndPosn - intStartPosn), ".", ","))
                strErrMsg = ""
                If Err.Number <> 0 Then
                    strErrMsg = "Error parsing for " & strTicker & "."
                    blnError = True
                    intErrorCount = intMaxErrCount
                    Err.Clear
                End If
            Else
                ' Major Error
                strErrMsg = "Fail"
            End If
        End If
        Set xmlHttpDoc = Nothing
    Wend

    If strErrMsg <> "" Then
        GetQuote = strErrMsg
    Else
        GetQuote = (dblQuote / 100)
    End If
    
   

End Function



Автор: ИгнатьевАлексей 5.2.2008, 09:34
Pogreb, функция отличается тем, что возвращает какое то значение. То есть подразумевается, что это значение используется также в программе.
Если я правильно понял, тебе надо периодически получать значение из нета при помощи этой функции и загонять полученное значение в ячейку(и)?
Тогда пишешь маленький макросик, который вызывает эту функцию и полученное значение пишет в нужную ячейку. А запускать макросы периодически ты умеешь.  smile 

Автор: Pogreb 5.2.2008, 10:28
Ну это можно конечно, только мне интересно было, можно ли написать таким образом, чтобы можно было "растянуть на колонку", а с макросом наверное так не получится. Просто я не шарю в программухе сильно, если не сложно, помогите ))

Автор: ИгнатьевАлексей 5.2.2008, 13:58
Pogreb, помогу с удовольствием, а писать за тебя нет время  smile 

1. Функция работает? Ты получаешь с помощью нее то, что надо?

2. Ты хочешь, чтобы макрос запускался периодически сам и помещал в ячейку полученную инфу? 

3. Каким образом тебе надо заносить полученную инфу? Что такое - "Растянуть на колонку"?

Русский язык велик и могучь  smile 

Автор: Pogreb 5.2.2008, 18:32
1)Да функция работает и возвращает верные значения.

2)Да я хочу чтобы макрос запускался периодически, запускал функцию, функция обновляла значения в клетке.

Растянуть на колонку, я имел ввиду когда у меня в ячейке введена функция к примеру =getquote(A3). в ячейке А3 содержится параметр функции, чтобы можно было растянуть, взять эту ячейку с формулой и растянуть на колонку и чтобы она выдала мне результаты в соответствии с А колонкой параметров.

А что значит, каким образом заносить информацию?
Мне надо, чтобы в той ячейке, где у меня написана функция, просто возращалось значение этой функции и периодически обновлялось. 
Конечно можно написать макрос, чтобы он запускал функцию, но его придется каждый раз переписывать, если добавить или удалить ячейку. А тем более если распложить ее в другой колонке или строке.

Я надеюсь я все понятно написал  smile 

Автор: Naghual 5.2.2008, 22:26
Функцию оставьте в покое.
А периодически инициируйте пересчет листа. Для этого существует метод CALCULATE.

Автор: Pogreb 6.2.2008, 01:34
Может подскажете куда надо всунуть этот метод. 
В эту же функцию? или надо создать другую?

Автор: ИгнатьевАлексей 7.2.2008, 10:32
Pogreb, теперь понятнее

Растянуть на колонку - все должно так и происходить, как ты ждешь, если перед номером столбца или строки не стоит значек   $    . $ - закрепляет номер столбца или строки при копировании протяжкой.

Дальше делай то, что  Naghual тебе подсказывает. Пишешь простейший макросик, который активирует метод  Calculate своего листа, или его части. Макросик запускаешь на выполнение с нужной периодичностью - это обсуждали

Вот - из хелпов:

Calculate Method
See AlsoApplies ToExampleSpecificsCalculates all open workbooks, a specific worksheet in a workbook, or a specified range of cells on a worksheet, as shown in the following table.

To calculate Follow this example 
All open workbooks Application.Calculate (or just Calculate) 
A specific worksheet Worksheets(1).Calculate 
A specified range Worksheets(1).Rows(2).Calculate 

expression.Calculate
expression    Optional for Application, required for Worksheet and Range. An expression that returns an object in the Applies To list.

Example
This example calculates the formulas in columns A, B, and C in the used range on Sheet1.

Worksheets("Sheet1").UsedRange.Columns("A:C").Calculate


Удачи

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)