UDF получения 2 последних символов с имени листа [РЕШЕНО]

Автор Aleksandr H., 23 сентября 2014, 23:34

0 Пользователи и 1 гость просматривают эту тему.

Aleksandr H.

Хочу сделать чтобы в ячейку А1 автоматически вписовалось 2 последних симовола от имени листа. Например: имя листа "Тиждень 39", то в ячейке А1 - "39". И так на каждом листе, в зависимости от его имени, было соответсвующее значение в ячейке А1.
Написал такую функцию
function get2RightSymbols () as string
Dim Sheet As Object
oSheet=ThisComponent.getCurrentController().getActiveSheet() ' получения активного листа
   get2RightSymbols = RIGHT(oSheet.getName,2)
end function


Вызов: в ячейке А1 формула :"=get2RightSymbols ()"
Вылетает ошибка при откритии файла. Как понимаю, ошибка в строке oSheet=ThisComponent.getCurrentController().getActiveSheet().
Как изменить функцию чтобы она возвращала 2 последних символа имени листа без ошибки?

rami

Немножко поправил:
Function get2RightSymbols() As String
Dim oSheet As Object
oSheet=ThisComponent.CurrentController.ActiveSheet ' получения активного листа
get2RightSymbols=RIGHT(oSheet.Name,2)
End Function
Функция в ячейке:   =GET2RIGHTSYMBOLS()

Aleksandr H.


rami

Цитата: Aleksandr H. от 24 сентября 2014, 00:12все та же ошибка
Удалите вашу функцию и скопируйте мою. У меня работает.
А документ открыт? Почему нет контролёра?

Aleksandr H.

Ошибка при откритии документа

rami

Цитата: Aleksandr H. от 24 сентября 2014, 00:55Ошибка при откритии документа
Попробуйте так:
Function get2RightSymbols() As String
Dim oSheet As Object, x$
oSheet=ThisComponent.CurrentController.ActiveSheet ' получения активного листа
x=RIGHT(oSheet.Name,2)
get2RightSymbols=x
End Function

Aleksandr H.

Все равно ругается на отсутсвие CurrentController

rami

#7
Если функция в библиотеке Standard, то работает, а в другой нет.
Можно почитать здесь:http://forumooo.ru/index.php/topic,2349.0.html
Цитата: Aleksandr H. от 23 сентября 2014, 22:34Хочу сделать чтобы в ячейку А1 автоматически вписовалось 2 последних симовола от имени листа. Например: имя листа "Тиждень 39", то в ячейке А1 - "39". И так на каждом листе, в зависимости от его имени, было соответсвующее значение в ячейке А1.
Но я бы делал не через функцию, а через Sub:Sub RightSymbols
For i=0 To ThisComponent.Sheets.Count-1
oSheet=ThisComponent.Sheets(i)
oSheet.getCellRangeByName("A1").setString(RIGHT(oSheet.Name,2))
Next
End Sub

Hasim

Цитата: Aleksandr H. от 23 сентября 2014, 22:34Вылетает ошибка при открытии файла. Как понимаю, ошибка в строке
Код:
oSheet=ThisComponent.getCurrentController().getActiveSheet()
Вставьте, например, MsgBox "f" в исходный код функции
function get2RightSymbols () as string
Dim Sheet As Object
MsgBox "f"
oSheet=ThisComponent.getCurrentController().getActiveSheet() ' получения активного листа
    get2RightSymbols = RIGHT(oSheet.getName,2)
end function

закройте и снова откройте файл.
И увидите, что этот код выполняется тогда, когда нет еще самого листа (нет CurrentController).

JohnSUN

Попробуй формулу
=RIGHT(CELL("FILENAME";A1);2+INT(RAND()))
или просто
=RIGHT(CELL("FILENAME";A1);2)
+INT(RAND()) - просто для быстрого отображения нового номера в случае переименования листа. Если листы не будут переименовываться или это будет происходить редко, то эта добавка не нужна - достаточно будет нажать Ctrl+Shift+F9
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Hasim

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

Но здесь проявилась весьма ОБЩАЯ ПРОБЛЕМА: как заставить без ошибок работать подобные функции?

JohnSUN

Для общих проблем разработаны общие решения: вначале с помощью обработчиков On {[Local] Error GoTo Labelname | GoTo 0 | Resume Next} локализуется место возникновения ошибки, а затем с помощью серии операторов If...Then...Else изменяется логика проблемного фрагмента кода.
Цитата: Hasim от 24 сентября 2014, 12:42как заставить без ошибок работать подобные функции?
Только одним способом - писать их без ошибок, начинать код каждой из них с проверок всех нужных параметров на допустимость. В данном случае, достаточно развалить длинную строку получения текущего листа на три последовательных оператора и после выполнения каждого из них проверить результат на NULL
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Hasim

Маловато будет.

А лучше привести работающий пример, хотя бы для этой функции.

(Для других подобных функций это тоже сработает, если будет решение в общем виде.)

Кто возьмется?

JohnSUN

Цитата: Hasim от 24 сентября 2014, 13:33Маловато будет.
Не вопрос, держи побольше:
Function get2RightSymbols() As String
Dim oDoc As Object
Dim oCntrl As Object
Dim oSheet As Object
get2RightSymbols = "??"
oDoc = ThisComponent
If IsNULL(oDoc) Then
Exit Function
Else
oCntrl = oDoc.getCurrentController()
If IsNULL(oCntrl) Then
Exit Function
Else
oSheet = oCntrl.getActiveSheet()
If IsNULL(oSheet) Then
Exit Function
Else
get2RightSymbols = RIGHT(oSheet.getName(),2)
EndIf
EndIf
EndIf
End Function
Слишком длинно? Запиши лаконичнее:
Function get2RightSymbols() As String
Dim oDoc As Object
Dim oCntrl As Object
Dim oSheet As Object
get2RightSymbols = "??"
oDoc = ThisComponent
If IsNULL(oDoc) Then Exit Function
oCntrl = oDoc.getCurrentController()
If IsNULL(oCntrl) Then Exit Function
oSheet = oCntrl.getActiveSheet()
If IsNULL(oSheet) Then Exit Function
get2RightSymbols = RIGHT(oSheet.getName(),2)
End Function

Цитата: Hasim от 24 сентября 2014, 13:33А лучше привести работающий пример, хотя бы для этой функции.
Тоже не вопрос:
Function get2RightSymbols(Optional numOfSheet As Long) As String
If IsMissing(numOfSheet) Then numOfSheet = -1
If numOfSheet < 0 Or numOfSheet > ThisComponent.getSheets().getCount() Then
get2RightSymbols = "??"
Else
get2RightSymbols = RIGHT(ThisComponent.getSheets().getByIndex(numOfSheet-1).getName(),2)
EndIf
End Function
Вызывается такая функция с параметром SHEET()
=GET2RIGHTSYMBOLS(SHEET())
Если забыл его указать - ругаться не будет, выведет знаки вопроса и выполнение продолжится.
Фокус решения? Отказаться от использования объекта, существование которого мы не можем гарантировать на время запуска макроса - от CurrentController'а.
Цитата: Hasim от 24 сентября 2014, 13:33
(Для других подобных функций это тоже сработает, если будет решение в общем виде.)
Не будет решения в общем виде. Будут "напридуманные всякие обходные варианты для частных случаев", в этом и заключается работа программиста.
Цитата: Hasim от 24 сентября 2014, 13:33
Кто возьмется?
Уступаю
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Hasim

Цитата: JohnSUN от 24 сентября 2014, 13:52Цитата: Hasim от Сегодня в 13:33
А лучше привести работающий пример, хотя бы для этой функции.
Тоже не вопрос:
Когда я просил привести работающий пример, я имел в виду готовый файл, который можно скачать, запустить, проверить и изучить.

А не длиннющее описание того, как это нужно бы сделать .