Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

22 Сентябрь 2017, 19:51 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
Новости: Часто задаваемые вопросы по LibreOffice и Apache OpenOffice.org
 
   Начало   Помощь Поиск Войти Регистрация    задать вопрос  
Страниц: 1   Вниз
  Печать  
Автор Тема: Проблема с IsError?. BASIC runtime error. '91' Object variable not set.  (Прочитано 810 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Al_Ex
Новичок
*
Offline Offline

Сообщений: 32


« Стартовое сообщение: 24 Май 2017, 11:21 »

И снова я со своим мегамакросом Улыбка
В принципе запустил его в Либре, в дебажном режиме довольно далеко забежал, но споткнулся неожиданно на простой проверке в одной из функций.
Вся функция, написанная на VBA in Excel:
Код:
Public Function strCheckActiveCellValue() As String
    If Left(ActiveCell.Formula, 1) = "=" Then
        If ActiveCell.Value = "" Then
            strCheckActiveCellValue = """"""
        Else
            strCheckActiveCellValue = Right(ActiveCell.Formula, Len(ActiveCell.Formula) - 1)
        End If
    Else
If IsError(ActiveCell.Value) Then
            strCheckActiveCellValue = ActiveCell.Text
        Else
            If IsEmpty(ActiveCell.Value) Then
                strCheckActiveCellValue = ActiveCell.Value
            Else
                strCheckActiveCellValue = ActiveCell.Text
            End If
        End If
    End If
End Function

Падает на
Код:
If IsError(ActiveCell.Value) Then

Выдает ошибку
BASIC runtime error. '91'
Object variable not set.

Погуглив, так и не понял в чем проблем - тут нужен другой синтаксис? Хотя аналога не нашел. Или проблема в чем-то другом?
« Последнее редактирование: 24 Май 2017, 11:34 от Al_Ex » Записан
mikekaganski
Ветеран
*****
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 580


« Ответ #1: 24 Май 2017, 11:48 »

Сначала проверяйте на IsEmpty. IsError ожидает проинициализированную переменную (Value). Вообще, проверять значение до того, как вообще установить, что значение есть - это логическая ошибка. Хотя в Бейсике и не такое бывает Улыбка

Хе. Только заметил, что IsError делает то же самое, что и не-IsEmpty. Так что IsError тут просто вообще лишний Улыбка
« Последнее редактирование: 24 Май 2017, 12:03 от mikekaganski » Записан

С уважением,
Михаил Каганский
Al_Ex
Новичок
*
Offline Offline

Сообщений: 32


« Ответ #2: 24 Май 2017, 12:05 »

Наверное я еще не разобрался в физике процесса.
Я же проверяю содержимое активной ячейки. Активная ячейка определяется другими методами, где устанавливается курсор в определенную позицию, и мне нужно знать ее содержимое. Даже если ячейка пустая, это тоже корректный результат, который обрабатывается отдельно и будет участвовать в дальнейших расчетах. Как в таком случае работает IsError, он не понимает, что нужно проверить содержимое активной ячейки?
Записан
mikekaganski
Ветеран
*****
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 580


« Ответ #3: 24 Май 2017, 12:12 »

IsError вообще ничего не понимает, это не человек.

В эту функцию передаётся переменная (ActiveCell.Value). Не ячейка, а переменная в объекте. Она, как видно из кода, может быть пустой (IsEmpty), то есть не содержать значения. IsError проверяет, является ли значение переменной ошибкой. То есть она ожидает, что значение есть. Да, теоретически можно в начало реализации этой функции запихать проверку на пустую переменную, но так не сделали.

Всегда *сначала* проверяется, есть ли значение (IsEmpty), если есть - тогда уже какое оно (IsError, IsNull, etc).
Записан

С уважением,
Михаил Каганский
rami
Гуру
*******
Offline Offline

Пол: Мужской
Сообщений: 2 183


MacBook Pro, LibreOffice и Apache OpenOffice


« Ответ #4: 24 Май 2017, 12:16 »

Как в таком случае работает IsError, он не понимает, что нужно проверить содержимое активной ячейки?
А что, содержимое ячейки "объект" Непонимающий и этот объект может быть ошибкой?
Записан

rami
Гуру
*******
Offline Offline

Пол: Мужской
Сообщений: 2 183


MacBook Pro, LibreOffice и Apache OpenOffice


« Ответ #5: 24 Май 2017, 12:29 »

Если содержимое ячейки совсем уж не известно, наверно, лучше использовать следующие функции проверки типа:
Код:
TypeName(variable)   'Возвращает имя типа объекта в виде строки.
или
VarType(variable)    'Возвращает тип переменной в виде целого числа.
Записан

Al_Ex
Новичок
*
Offline Offline

Сообщений: 32


« Ответ #6: 24 Май 2017, 13:22 »

Изначально код писал не я, да и у меня самого познаний в этом деле еще мало, поэтому "плаваю" нормально, но пытаюсь читать/учиться.
Согласен, что в указанной функции можно избавиться от IsError, т.к. по условию оно лишнее, но вот еще есть одна функция, где также присутствует IsError
Код:
Sub RecordValueToStatusAndDifferentErCell()
    Dim strRefFirstCell As String                                                                                               'Declare variable for reference of first cell
    Dim strRefSecondCell As String                                                                                              'Declare variable for reference of second cell
    Dim strRefThirdCell As String                                                                                               'Declare variable for reference of third cell
       
    ActiveCell.Offset(0, -3).Select                                                                                             'Activate cell with from "B" cell
    strRefFirstCell = ActiveCell.Address(RowAbsolute:=False, ColumnAbsolute:=False)                                             'Assigned ref by first cell to the variable
    ActiveCell.Offset(0, 2).Select                                                                                              'Activate cell with from "D" cell
    strRefSecondCell = ActiveCell.Address(RowAbsolute:=False, ColumnAbsolute:=False)                                            'Assigned ref by first cell to the variable
    ActiveCell.Offset(0, 1).Select                                                                                              'Activate cell with from "E" cell
    strRefThirdCell = ActiveCell.Address(RowAbsolute:=False, ColumnAbsolute:=False)                                             'Assigned ref by first cell to the variable
        If IsError(ActiveCell.Value) Then                                                                                       'If active cell value is error
            ActiveCell.Offset(0, 1).Select                                                                                      'Activate cell in "F" column
            Call PassFailAccordingWithLocalePart1(strRefFirstCell, strRefSecondCell, strRefThirdCell)
        Else                                                                                                                    'If active cell value isn't error
            Call PassFailAccordingWithLocalePart2(strRefFirstCell, strRefSecondCell, strRefThirdCell)
        End If
    End If
End Sub

Как здесь нужно переписать? Так не работает:
 If IsError(IsEmpty(ActiveCell.Value)) Then
или
 If IsError(TypeName(ActiveCell.Value)) Then   
Чувствую, что бред написал, но не понимаю, как это правильно обработать.
Записан
rami
Гуру
*******
Offline Offline

Пол: Мужской
Сообщений: 2 183


MacBook Pro, LibreOffice и Apache OpenOffice


« Ответ #7: 24 Май 2017, 14:12 »

Как здесь нужно переписать? Так не работает:
 If IsError(IsEmpty(ActiveCell.Value)) Then
или
 If IsError(TypeName(ActiveCell.Value)) Then   
Чувствую, что бред написал, но не понимаю, как это правильно обработать.
Если бы была функция IsBred(), она бы всегда возвращала значение "абсолютная правда" Смеющийся Смеющийся Смеющийся


1. IsEmpty(ActiveCell.Value) возвращает true или false, в любом случае это не годится для IsError()
2. TypeName(ActiveCell.Value) возвращает строковое значение, что тоже не годится для IsError()

Мне кажется, вы хотите "приделать пропеллер к чемодану без ручки"  Смеющийся вместо того, чтобы выкинуть его и сделать что-нибудь подходящее на замену.
Записан

Al_Ex
Новичок
*
Offline Offline

Сообщений: 32


« Ответ #8: 30 Май 2017, 18:50 »

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

Код:
Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
  IsInArray = (UBound(Filter(arr, stringToBeFound, True, vbTextCompare)) > -1)
End Function

Код:
Sub ErCell()
    Dim errorArray As Variant
    errorArray = Array("#N/A", "#DIV/0!", "#VALUE!", "#NAME?", "#NULL!", "#REF!", "#NUM!")
    If IsInArray(ActiveCell.Text, errorArray) Then                                                                         
        ActiveCell.Offset(0, 1).Select                                                                                       
        Call Func1(strRefFirstCell, strRefSecondCell, strRefThirdCell)
    Else                                                                                                                       
        Call Func2(strRefFirstCell, strRefSecondCell, strRefThirdCell)
    End If
End Sub

В Экселе такой код работает, правда не совсем корректно. Если в ячейке попадается цифра 0, то она матчится с ошибкой #DIV/0!, в которой есть эта цифра. Поигрался разными вариантами работы с функцией Filter, но так и не нашел варианта, чтобы искалось совпадение целиком.
А в Либре этот код вообще не хочет работать и на первой же итерации возникает ошибка: "BASIC runtime error. '35' Filter".
Как еще можно обыграть эту ситуацию?
Записан
Al_Ex
Новичок
*
Offline Offline

Сообщений: 32


« Ответ #9: 31 Май 2017, 12:56 »

Если содержимое ячейки совсем уж не известно, наверно, лучше использовать следующие функции проверки типа:
Код:
TypeName(variable)   'Возвращает имя типа объекта в виде строки.
или
VarType(variable)    'Возвращает тип переменной в виде целого числа.

Тоже хороший вариант, и простой, но...
В Экселе такая конструкция работает
Код:
   If TypeName(ActiveCell.Value) = "Error" Then
И оно действительно возвращало тип Error если находило ошибку.
В Либре какой бы тип данных не находился в ячейке, все время возвращается тип Double.
Если заменить на ActiveCell.Text, то соответственно всегда будет тип String.
Получается в случае нахождения ошибки тип определяется неверно и дальнейшие действия не проходят.
Записан
Страниц: 1   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!