Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Программирование в бесплатных офисных программах (Open Office и т.п.) > Ошибка компиляции: object variable not set


Автор: Severyanin 1.1.2014, 19:40
Добрый день. Пытаюсь адаптировать скрипт Vit'a (Царствие ему небесное) Reiteration ( который находит в тексте повторения однокоренных слов на расстоянии, заданном пользователем) для использования под LibreOffice.
Код

REM  *****  BASIC  *****

Sub Main
    Reiteration
End Sub

' Функция подсчитывает количетсво слов в документе 
' Нам она нужна только для определения объема 
' оставшейся работы для скрипта
' Решает задачу "в лоб"
Function GetTotalWordsCount() As Integer
    Dim Doc As Object
    Dim Cursor As Object
    Dim WordsCount As Integer
    Dim Proceed As Boolean
    
    Doc = ThisComponent 
    Cursor = Doc.Text.createTextCursor
    
    WordsCount = 0
    Do
        WordsCount = WordsCount + 1
        Proceed = Cursor.gotoNextWord(False)
    Loop While Proceed

    GetTotalWordsCount = WordsCount
    
End Function

' Функция получения корня слова (работает только для русского языка)
Public Function GetRoot(s) As String
   GetRoot = ""

   s = Replace(Replace(Replace(Replace(Trim(s), ",", ""), ".", ""), ":", ""), "-", "")
   s = LCase(s)
   If Len(s) < 2 Then _
     Exit Function

   If Len(s) <= 4 And InStr("не ли ни то ну или если что без нет как либо то" _
                           , s) > 0 Then _
     Exit Function

   If Len(s) >= 2 And InStr("ой ая ое ам ям ом ем ин ём ся ет ит ут ют ат ят ыв ив ев ан ян ов ев ог ег ир ер ых ок ющ ущ er ed" _
                           , Right(s, 2)) > 0 Then _
     s = Left(s, Len(s) - 2)

   If Len(s) >= 3 And InStr("енн овл евл ённ анн ост ест" _
                           , Right(s, 3)) > 0 Then _
     s = Left(s, Len(s) - 3)

   If Len(s) = 0 Then _
     Exit Function

   If Left(s, 4) = "пере" Then
     s = Right(s, Len(s) - 4)
   Else
     If Len(s) >= 3 And InStr("при рас пре про под", Left(s, 3)) > 0 Then
       s = Right(s, Len(s) - 3)
     Else
       If Len(s) >= 2 And InStr("на за ис из до по вы во со", Left(s, 2)) > 0 Then
         s = Right(s, Len(s) - 2)
       Else
         If InStr("в с", Left(s, 1)) > 0 Then
           s = Right(s, Len(s) - 1)
         End If
       End If
     End If
   End If
  GetRoot = s
End Function

Sub Reiteration
'
 ' ********************  В помощь писателю  ******************************
 ' *          Этот макрос выделяет повторы слов в тексте                 *
 ' *                                                                     *
 ' * Copyright (c) Vitaly Nevzorov, 2008, [email protected]             *
 ' * Распространение свободное :)                                        *
 ' * Пользуйтесь на здоровье!                                            *
 ' *                                                                     *
 ' * Вы можете настроить чувствительность, по умолчанию выделяются       *
 ' * все однокоренные слова, находящиеся на расстоянии менее 10 слов     *
 ' * в следующей строке вы можете поставить другую чувствительность:     *
    Const Sensitivity = 10
 ' *                                                                     *
 ' * Alexandr Sysoev - Внесён ряд изменений:                             *
 ' *  1 - Переделан алгоритм с целью увеличения скорости работы.         *
 ' *      Скорость увеличена в 15-20 раз!                                  *
 ' *  2 - Добавлен замер времени выполнения                              *
 ' *  3 - Исправлена ошибка:                                             *
 ' *      Исходный вариант не находил повторы в конце документа, среди   *
 ' *      последних Sensitivity слов.                                    *
 ' *  4 - Исправлена неточность (спорная):                               *
 ' *      Исходный вариант учитывал незначащие слова (для которых        *
 ' *      функция GetRoot возвращает пустую строку) при вычислении       *
 ' *      расстояния. Мой вариант их не считает.                         *
 ' *  5 - В конец макроса добавлен вывод модального сообщения о          *
 ' *      завершении работы. Мне показалось так удобнее, хотя это спорно.*
 ' *  6 - Добавлен сброс атрибута подчеркивания для всего документа      *
 ' *      перед началом работы. Не уверен что это хорошо, поскольку      *
 ' *      может испортить пользовательское форматирование.               *
 ' *      Лучше наверное чистить более избирательно, но лень :).
 ' * Портировал для OpenOffice/LibreOffice Alexey Protchenko aka Severyanin, [email protected]
 ' ***********************************************************************

    Dim Doc As Object
    Dim Cursor As Object
    Dim Proceed As Boolean
    Dim Total,Found,i,J,N As Integer
    Dim W As String
    Dim WDict(Sensitivity - 1)
    Dim WRanges(Sensitivity - 1)  As Object
    
    Doc = ThisComponent 
    Cursor = Doc.Text.createTextCursor
    
    Total = GetTotalWordsCount()
    'MsgBox CStr(Total)
    i = 0
    N = 0
    Found = 0
    Do
        Cursor.gotoEndOfWord(True)
        i = i + 1
        W = GetRoot(Cursor.String)
        If Len(W) > 1 Then
            For J = 0 To Sensitivity - 1
                If W = WDict(J) Then
                  Cursor.gotoEndOfWord(True)
                  Cursor.CharUnderline = com.sun.star.awt.FontUnderline.DOUBLEWAVE
                  Cursor.CharColor = com.sun.star.util.Color.blue
                    Found = Found + 1        
                    
                End If
          Next J
        
NextIter:    WDict(N) = W
          Set WRanges(N) = WR
          N = (N + 1) Mod Sensitivity
        End If
        Proceed = Cursor.gotoNextWord(False)
    Loop While Proceed
    MsgBox "Найдено повторов слов: " & Round(Found * 100 / Total, 2) & "%"
End Sub

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

    If W = WDict(J) Then
                  Cursor.gotoEndOfWord(True)
                  Cursor.CharUnderline = com.sun.star.awt.FontUnderline.DOUBLEWAVE
                  Cursor.CharColor = com.sun.star.util.Color.blue
                    Found = Found + 1        
                    Exit For
                End If

 на строке Exit For вываливается сабжевая ошибка. Причем если строку заекомментить, ошибка указывает на нее же. При удалении - на предыдущую. Не могу отловить причину ошибки - все переменные объявлены ранее и инициализированы. Буду очень благодарен за помощь.
С уважением, Северянин

Добавлено через 1 минуту и 49 секунд
P.S. Ошибка вываливается при компиляции. Версия LibreOffice: 4.0.2.2 (Build ID: 400m0(Build:2)) ОС - Linux Mint 15 olivia

Автор: Akina 1.1.2014, 21:49
В данном случае вместо Exit For можно использовать Goto NextIter - попробуй.
Но проблема связана не с этим блоком, а (судя по тому, что ты пишешь) с объектом Cursor. Исправь там код - например, те же Set правильно расставь.

Автор: Severyanin 2.1.2014, 19:01
Да, спасибо большое. Передергивал курсор 2 раза. Попробую отловить остальные баги

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