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

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

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

Войти
Новости: Здесь можно поблагодарить участников форума Улыбка
 
   Начало   Помощь Поиск Войти Регистрация    задать вопрос  
Страниц: « 1 2 3 4 5 6 7 »   Вниз
  Печать  
Автор Тема: Возможно ли создать многостраничную форму в LO Base  (Прочитано 18795 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Kadet
Форумчанин
***
Offline Offline

Сообщений: 635


« Ответ #60: 10 Декабрь 2019, 11:37 »

Лист достаётся без проблем. Он у меня даже в глобальной переменной зашит.
Но в этом листе при нажатии любой из кнопок активной ячейкой является нулевая ячейка (0,0) по-умолчанию, или какая-нибудь другая, в которой ранее кликал, а не та, к которой привязана нажимаемая кнопка. А мне нужна именно эта ячейка, в которой сидит кнопка, которую я сейчас нажимаю. По сути нужен один только номер строки (oRow), в которой находится эта кнопка.
Записан
mikekaganski
Гуру
*******
Offline Offline

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


« Ответ #61: 10 Декабрь 2019, 12:24 »

Нет прямого способа найти привязку кнопки (вот не знаю уж почему). Единственный вариант - это перебрать все элементы на текущей DrawPage (циклом по DrawPage(i) до DrawPage.Count-1), сравнивать у каждого элемента, является ли модель тем же объектом, что и модель текущего события (EqualUnoObjects), и уже тогда получить Anchor найденного объекта:

Код:
Function GetAnchor(ByRef oButton As Object) As Object
Dim oDrawPage As Object, i As Long, obj As Object
oDrawPage = ThisComponent.CurrentController.ActiveSheet.DrawPage
For i = 0 To oDrawPage.Count - 1
obj = oDrawPage(i)
If (EqualUnoObjects(obj.Control, oButton)) Then
GetAnchor = obj.Anchor
Exit Function
End If
Next i
End Function

...

buttonAnchor = GetAnchor(oEvent.Source.getModel())

Вот ещё более общий вариант получения якоря, не полагающийся на текущий компонент и его активный контроллер:

Код:
Function GetAnchor(ByRef oButton As Object) As Object
Dim oDrawPages As Object, oDrawPage As Object, i As Long, j As Long, obj As Object
obj = oButton
Do While (Not(obj Is Nothing) And Not HasUnoInterfaces(obj, "com.sun.star.drawing.XDrawPagesSupplier"))
If (HasUnoInterfaces(obj, "com.sun.star.container.XChild")) Then
obj = obj.Parent
Else
obj = Nothing
End If
Loop
If (Not(obj Is Nothing)) Then
oDrawPages = obj.DrawPages
For i = 0 To oDrawPages.Count - 1
oDrawPage = oDrawPages(i)
For j = 0 To oDrawPage.Count - 1
obj = oDrawPage(j)
If (EqualUnoObjects(obj.Control, oButton)) Then
GetAnchor = obj.Anchor
Exit Function
End If
Next j
Next i
End If
End Function

Однако если идти в обход не претит, то возможно, всё же быстрее использовать дополнительно к свойству Name ещё и свойство Tag, и/или хранить всю информацию (и номер заказа, и номер строки, и ещё всё что угодно) в одной строке, разделённой спецсимволами (например, "|" или вообще недоступными пользователю, типа Chr(1)), и пользовать Split для получения массива значений из такой строки.
« Последнее редактирование: 10 Декабрь 2019, 13:07 от mikekaganski » Записан

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

Сообщений: 635


« Ответ #62: 10 Декабрь 2019, 13:28 »

mikekaganski, спасибо! Самая простая идея, думаю, использовать таки свойство Tag для передачи номера строки.

А я так хотел уйти от перебора. Там можно и гораздо проще сделать. Дело в том, что в 0 столбце этой же строки, в которой кнопка, занесено тоже значение номера заказа. И можно просто перебором сравнивать все значения нулевого столбца, пока не будет совпадения с Name кнопки.

Однако, всё таки, сдаётся мне, что есть какой-то метод прямого доступа к адресу привязки.
Ну а пока, попробую Tag или перебор ячеек.
Записан
mikekaganski
Гуру
*******
Offline Offline

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


« Ответ #63: 10 Декабрь 2019, 14:24 »

Однако, всё таки, сдаётся мне, что есть какой-то метод прямого доступа к адресу привязки.
Да нет такого метода.
Когда вызывается событие, его источник - элемент формы. У форм и их элементов нет знания о их родительском листе (DrawingPage). У формы есть набор своих объектов (view - со своими свойствами), которые ссылаются на модель кнопки. А у DrawingPage - свои объекты view (со своими свойствами, в числе которых привязка), ссылающиеся на ту же модель. Модель вообще ничего о своих view не знает. Так что перебор - единственный доступный способ.

Конечно, можно ещё воспользоваться тем, что кнопка позволяет добавлять себе свойства динамически - но при наличии Tag это в общем-то не добавляет ничего полезного.
Записан

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

Сообщений: 635


« Ответ #64: 10 Декабрь 2019, 14:32 »

Проверил метод Tag. Прекрасно работает. Спасибо за идею.
Записан
mikekaganski
Гуру
*******
Offline Offline

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


« Ответ #65: 10 Декабрь 2019, 14:48 »

Да кстати, у Вас постоянно кнопки добавляются, но не удаляются. При очистке делатей кнопки остаются болтаться, и там их у вас накопится столько, что оно начнёт падать. Так что всё-таки Вам понадобится искать ControlShape для модели, и удалёть его с DrawPage в DETAL_del:

Код:
Function GetControlShape(ByRef oButton As Object) As Object
Dim oDrawPages As Object, oDrawPage As Object, i As Long, j As Long, obj As Object
obj = oButton
Do While (Not(obj Is Nothing) And Not HasUnoInterfaces(obj, "com.sun.star.drawing.XDrawPagesSupplier"))
If (HasUnoInterfaces(obj, "com.sun.star.container.XChild")) Then
obj = obj.Parent
Else
obj = Nothing
End If
Loop
If (Not(obj Is Nothing)) Then
oDrawPages = obj.DrawPages
For i = 0 To oDrawPages.Count - 1
oDrawPage = oDrawPages(i)
For j = 0 To oDrawPage.Count - 1
obj = oDrawPage(j)
If (HasUnoInterfaces(obj, "com.sun.star.drawing.XControlShape")) Then
If (EqualUnoObjects(obj.Control, oButton)) Then
GetControlShape = obj
Exit Function
End If
End If
Next j
Next i
End If
End Function

Sub DETAL_del(oEvent)
Dim oDoc, oController, oSheet, oRange, oRow, oShape

oDoc = ThisComponent

oDoc.lockControllers()
On Error GoTo Cleanup

oController = oDoc.CurrentController

oSheet = oDoc.sheets(0)
oShape = GetControlShape(oEvent.Source.getModel())
oRow = CInt(oEvent.Source.getModel().Name)
HideRows1(oDoc, oSheet, oRow-1, oRow)
oSheet.DrawPage.remove(oShape)
oRange = oSheet.getCellRangeByPosition(0,oRow-1,100,oRow)
oRange.clearContents(255)
oRange = oSheet.getCellRangeByPosition(11,oRow-2,11,oRow-2)
oController.select(oRange)

Cleanup:
oDoc.unlockControllers()
End Sub
Записан

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

Сообщений: 635


« Ответ #66: 10 Декабрь 2019, 16:52 »

А разве "oRange.clearContents(1023)" не удаляет все хвосты? Мне Rami рекомендовал этим методом пользоваться и говорил, что все хвосты подчищает "одним движением"?!.
Записан
mikekaganski
Гуру
*******
Offline Offline

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


« Ответ #67: 10 Декабрь 2019, 17:49 »

Ну, непонятно происхождение константы 1023 (в коде у Вас вообще 255 - см. тут). Но таки да, попытка очистки производится - но тут есть закавыка. Объект должен полностью находится внутри удаляемого диапазона, и это накладывает ограничения. Во-первых, нельзя просто взять размер ячейки и назначить кнопке (вы так и не делали - Вы назначили высоту на 50 меньше, что помогло ... бы, если бы не); во-вторых, удаление должно быть не в скрытом диапазоне: скрытый диапазон имеет высоту 1, тогда как высота кнопки больше -> никогда кнопка не окажется внутри скрытого диапазона.

Так что проще и надёжнее объекты удалять вручную.
Записан

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

Сообщений: 635


« Ответ #68: 10 Декабрь 2019, 19:08 »

А если просто удалить всю форму, в которой сидят эти кнопки, да ещё сверху "полирнуть" clearContents(1023)?
Я всё же не пойму. Вначале я делал так - удалял всю форму, в которой формировались кнопки, а ячейки чистил clearContents(255) (нашёл этот параметр эмпирическим путём). Rami сказал, что проще и лучше чистить просто clearContents(1023), мол при прежнем методе остаются некие невидимые рамки и следы от кнопок.
Теперь выясняется, что и clearContents(1023) не может всё почистить до конца.

Дабы избежать ненужных подений базы, которые случаются, я бы хотел разобраться. Не очень хочется запускать достаточно массивный и громоздкий чистильщик, в особенности когда мои юзеры весьма нетерпеливые и тыкают всё время куда попало, не дожидаясь окончания процедур (а закрывать такие возможности тоже нельзя ибо будет хуже).
Так вот, есть ли возможность посмотреть после проведённой чистки почистился ли лист calc до конца или таки нет?
« Последнее редактирование: 10 Декабрь 2019, 19:11 от Kadet » Записан
rami
Гуру
*******
Offline Offline

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


iMac, LibreOffice и Apache OpenOffice


« Ответ #69: 10 Декабрь 2019, 22:06 »

А если просто удалить всю форму, в которой сидят эти кнопки, да ещё сверху "полирнуть" clearContents(1023)?
Тогда и кнопка запуска макроса "Кнопка" сотрётся.

Теперь выясняется, что и clearContents(1023) не может всё почистить до конца.
clearContents(1023) чистит всё, но и clearContents(255) может быть достаточно для ваших целей. Если скрываемый диапазон меньше чем очищаемый, то удаляет нормально. А зачем вы скрываете?
Записан

Kadet
Форумчанин
***
Offline Offline

Сообщений: 635


« Ответ #70: 10 Декабрь 2019, 22:34 »

Вообще-то под скрываемым диапазоном у меня ничего никогда нет... не должно быть.
Там как бы несколько скрытых диапазонов. От 0 до 100 это раздел набора деталей. А всё, что свыше - не переделанные остатки от прежних не совсем удачных идей. Поначалу я вообще делал "красоту", прорисовывая слои и много слойные "пачки" в зависимости от количества штук заготовок того или иного раскроя. Прорисовку делал узенькими и тоненькими ячейками с прорисовкой сетки. Получилось весьма сложно, длительно и, вопреки ожиданиям, не красиво. В итоге основную часть хвостов от этой идеи я почистил, а часть неуглядел. Да и времени на это не было. Глубоко не стал заморачиваться. Может быть сейчас займусь и подчищю остатки.

Вообще, многослойность скрытых разделов не редко использую в своей базе. В частности это помогает мне зафиксировать некоторые ячейки на ключевых местах, и уже до заполнения внутренних (между разделами) данных, число которых заранее неизвестно, иметь доступ к этим ключевым точкам. В частности по ним я иногда считаю суммы, которые нельзя заранее просчитать... Или ими же отсекаю виды/группы товаров и т.п.
Можно, конечно, и по-другому решить эти вопросы. но мне показалось удобней решить их так.
« Последнее редактирование: 10 Декабрь 2019, 22:38 от Kadet » Записан
rami
Гуру
*******
Offline Offline

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


iMac, LibreOffice и Apache OpenOffice


« Ответ #71: 10 Декабрь 2019, 22:52 »

Если в скрываемых местах нет кнопок, то не понимаю в чём проблема со стиранием кнопок?

Kadet, есть идея с передачей нужных параметров помимо "Tag", с помощью "ActionCommand" события кнопки, это легко, нужно добавить одну строку кода в функцию "Sub AddButton(oCol, oRow, nam, label, width, color, macro)". Напишу в следующем ответе.
Записан

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

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


iMac, LibreOffice и Apache OpenOffice


« Ответ #72: 10 Декабрь 2019, 23:07 »

Нет прямого способа найти привязку кнопки (вот не знаю уж почему).
К ячейке привязывается не сама кнопка, а ControlShape внутри которой находится кнопка, с другой стороны, событие передаёт кнопку, а не ControlShape.

Свойство "Tag" используется как "записная книжка" у модели многих элементов управления, но у кнопки есть ещё один простой и более доступный метод (и свойство) "setActionCommand", это значение легко достаётся из события:
Код:
Sub AddButton(oCol, oRow, nam, label, width, color, macro)
Dim oSheet, vCell, oDrawPage, oControlShape, oButtonModel, sScriptURL$, oForm, but
Dim aSize As new com.sun.star.awt.Size
Dim aEvent As new com.sun.star.script.ScriptEventDescriptor

oSheet = oDoc.sheets(0)
oDrawPage = oSheet.DrawPage

oControlShape = oDoc.createInstance("com.sun.star.drawing.ControlShape")
vCell = oSheet.getCellByPosition(oCol, oRow)
oControlShape.setPosition(vCell.Position)
aSize.Width = width
aSize.Height = 400
oControlShape.setSize(aSize)

oButtonModel = CreateUnoService("com.sun.star.form.component.CommandButton")
oButtonModel.Label = label
oButtonModel.FontStyleName = "Полужирный"
oButtonModel.FontWeight = 150
oButtonModel.FontHeight = 10
oButtonModel.TextColor = color
oButtonModel.VerticalAlign = com.sun.star.style.VerticalAlignment.MIDDLE
oButtonModel.Name = nam & oRow
oButtonModel.Printable = False

oControlShape.setControl(oButtonModel)
oDrawPage.add(oControlShape)

'добавляем в событие для данной кнопки значение ActionCommand, например, имя и номер строки
oDoc.CurrentController.getControl(oButtonModel).setActionCommand("ActionCommand: " & nam & oRow)

sScriptURL = "vnd.sun.star.script:Standard.Module1." & macro & "?language=Basic&location=document"
oForm = oDrawPage.getForms().getByIndex(0)
With aEvent
.AddListenerParam = "asd"
.EventMethod = "actionPerformed"
.ListenerType = "XActionListener"
.ScriptCode = sScriptURL
.ScriptType = "StarScript"
End With
oForm.registerScriptEvent(oForm.Count-1, aEvent)

oControlShape.Anchor = vCell
oControlShape.MoveProtect = True
oControlShape.SizeProtect = True

oDoc.CurrentController.setFormDesignMode(false) 'выйти из режима редактирования
End Sub

Sub ButtonPushEvent(ev as com.sun.star.awt.ActionEvent) 'срабатывает при нажатии кнопок
msgbox ev.ActionCommand 'получаем значение ActionCommand
End Sub
Записан

Kadet
Форумчанин
***
Offline Offline

Сообщений: 635


« Ответ #73: 11 Декабрь 2019, 16:16 »

есть идея с передачей нужных параметров помимо "Tag", с помощью "ActionCommand" события кнопки
Добавил событие, по вашей рекомендации. Ожидал при нажатии кнопок увидеть некое сообщение по msgbox, но пока ничего не увидел. Попробую пошагово прогнать.
Записан
rami
Гуру
*******
Offline Offline

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


iMac, LibreOffice и Apache OpenOffice


« Ответ #74: 11 Декабрь 2019, 17:22 »

Если msgbox не вызывается, то макроось не назначался или что-то не срослось. К двум указанным макросам добавьте макрос DemoCalc из документа DEMO4 что я выложил раньше.
Записан

Страниц: « 1 2 3 4 5 6 7 »   Вверх
  Печать  
 
Перейти в:  

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