РЕШЕНО: Элемент управления Table Control - как определить текущий столбец?

Автор economist, 19 июня 2020, 16:50

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

economist

Элемент управления Таблица (во Writer/Calc вставляется Форма -> Таблица, мастер делает связь с таблицами/запросами базы данных *.ODB) - оказался удобным для выбора мышью несмежных строк. Есть Быстрый фильтр, Сортировка итп. А нащелканный мышью SQL-запрос (текущий фильтр) - можно легко прочитать, как и значение нужного столбца выделенной строки (т.е. одну ячейку).

Вопрос: А как определить текущий (с красной рамкой) столбец по событию grid_selectionChanged(ev)?

Ни одного API-примера реального использования не нагулил:
https://www.openoffice.org/api/docs/common/ref/com/sun/star/awt/grid/XGridControl.html#getCurrentColumn
https://www.openoffice.org/api/docs/common/ref/com/sun/star/awt/grid/XGridControl.html#getCurrentColumnPosition

Приложил файл с таблицей и связью с Biblio.odb, код макроса ниже:


Sub grid_selectionChanged(ev)
' назначен на Св-ва формы - События - После смены записи
Dim oRows() As Object
oRows = ev.Source
On Error Resume next
NamedCol = oRows.findColumn("Author")
msgbox " Значение яч.: " & oRows.getString(NamedCol)
msgbox " Текущий столбец: "     ' ??? как
On Error GoTo 0
End Sub
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

bk

getCurrentColumnPosition у Элемента управления Таблица не подходит?

economist

на все варианты

oRows.getCurrentColumnPosition()
oRows.getModel().getCurrentColumnPosition()
oRows.getModel().getParent().getCurrentColumnPosition()

Ошибка времени выполнения BASIC.
Свойство или метод не найдены: getCurrentColumnPosition

Если есть пример кода - покажите, возможно понимание объектной модели отсутствует ~:-\
Или неправильно обращаюсь к контролу из события. 
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

rami

Цитата: economist от 20 июня 2020, 00:59Или неправильно обращаюсь к контролу из события.
Вы вообще к нему не обращаетесь, вы обращаетесь к форме и получаете записи. Чтобы получить столбец, нужно обратиться к элементу управления Таблица.

В примере сделал вывод в документ под таблицей, вместо "msgbox"

bk

Из формы можно ещё так, но получается как-то криво (если имя столбца в одной строке кода уже известно, то зачем его искать? Хотя как задача стоит...):

Sub grid_selectionChanged(ev)
'назначен на Св-ва формы - События - После смены записи
Dim oRows
Dim NamedCol
oRows = ev.Source
On Error Resume next
  NamedCol = oRows.findColumn("Author")
  msgbox " Значение яч.: " & oRows.getString(NamedCol)
  msgbox " Текущий столбец (номер или имя): " & Rows.getColumns.getByName("Author").getName
On Error GoTo 0
End Sub

Просто у формы нет метода getCurrentColumnPosition, getCurrentColumn. Он есть у Элемента управления Таблица (Grid).

Кстати, NamedCol у Вас возвращает номер столбца, так что во втором сообщении вместо
Rows.getColumns.getByName("Author").getName если поставите
NamedCol, будет то, что надо.

economist

Спасибо огромное, @rami, вы подсказали путь как сделать самый эргономичный способ "подбора" нужных строк из больших таблиц, например остатков материалов. Анализируя по какому столбцу был клик - можно решать что и как возвращать (либо ничего не делать). Обработав раздельно события смены строки выделения Формы и клик в Контроле Формы - можно здорово улучшить юзабилити "прокручиваемых" таблиц во всех(!) редакторах LO - Writer/Calc/Base/Impress/Draw, сделав доступный там XGridControl самым полезным/востребованным контролом.

Пооффлю о его практичности, может кого воодушевит :-) В 1С/SAP/Галактика итп - очень муторные диалоги "подбора", заставляющие пользователя щелкать по ОК-кнопке либо ставить кучу флажков в трудносортируемом древовидном диалоге. Но это еще полбеды. Хуже что даже дорогие "коробки" 1С:УПП за 500 тыс. руб. или 1C:ERP2 за 1,5 млн. руб. - не покажут вам в форме подбора (кроме кол-ва) ничего другого важного - цены последней покупки, средней цены, у кого брали, сколько ему должны, когда ему прошлый раз платили и стоит ли обращаться :-) Подобная доработка в 1С возможна, но будет стоит 100 тыс. руб. и займет 2 месяца (реальный кейс).

А свободный LO Writer, подключенный к БД (путь даже это просто папка с TXT-файлами на чтение) - покажет вам в простом ODT-файле не только это, но и всё, о чем вы его ещё попросите. Соединить "остатки с долгами" может простой LEFT OUTER JOIN в SQL-запросе контрола Таблица (или в ODB-файле, или сразу формировать TXT-файл в быстром Python/Pandas). Ну, идею вы поняли...

Традиционные Списки, Поля со списками в Диалогах/Формах проигрывают контролу Таблица в наглядности и "охвате". Только у Таблиц есть готовые и легко программируемые Быстрые Фильтры и Сортировки, которые, к тому же, применяются не вместо, а "поверх" основного SQL-запроса. Их статус сохраняется при закрытии файла, а значит Заявка.odt (или даже Заявка.PDF), составленная утром - при открытии вечером обновит и покажет вам "свежие" остатки из БД (на вечер), а ниже таблицы останется то что было вставлено макросом утром, когда заявитель принимал решение "чего и сколько". "Живые" остатки/цены/поставщики в файлах заявок/договоров итп - помогут НЕ купить ненужное, втридорога, дешевку, некондицию, у кидал, у "уставшего" поставщика, у банкрота итп (если информация об этом уже хоть где-то есть - в XLS-файлах контактов, адресной книге ThunderBird итд). Кто-то заметит что для всего этого "существуют" CRM-системы, но они дороги, трудны и "знают" про бизнес далеко не всё. И прижились они только у банков и коллекторов :-(

Моим ИТР-заводчанам сразу "зашёл" контрол Таблица с его 7-ю кнопками сортировки и отключаемой быстрой/точной фильтрацией, с 4-мя(!) видами поиска (обычный, шаблонный, с регулярками, а также гибко настраиваемый "поиск подобных", идеально находящий слова с "очепятками" перестановки, "прпущенными" и "лишшними" буквами, что в 1С-ах часто, т.к. проверки орфографии в ней нет.

В текстах 10-ть коллег нашли за 2 контрольных минуты все 10-ть искомых строк материалов из 10k, причем каждый по-своему, хаотично жав кнопку Быстрый фильтр и пересортировку. Но получившийся oForm.Filter был в итоге логичен и читаем. А вот в 1С УПП это же задание заняло вдвое больше времени у 7/10, а 3/10 не нашли все строки вовсе.

Из минусов контрола Таблица пока вижу лишь один - установленные вручную форматы столбцов/данных и их ширина - часто слетают при фильтрации/сортировке, если источник данных Readonly (TXT-файлы через коннектор, а не через HSQLDB). Устранимо макросами.
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

economist

Цитата: bk от 20 июня 2020, 11:01Кстати, NamedCol у Вас возвращает номер столбца...

@bk, каюсь, криво сформулировал, хорошо что @rami меня понял :-). Нужно все-таки XRay/MRI/Ocean осваивать и зазубрить эту чертову объектную модель, которая ну очень непохожа на VBA MSO и трудно инспектируется. Вывод из топика сделал такой:

' Псевдокод. Назначить на событие Нажатие клавиши мыши на "Элем управления Таблица"
табличка  = event.Source  ' это сам кликнутый контрол, умеет getCurrentColumnPosition, но не умеет возвращать значения БД
формочка = event.Source.Model.Parent  ' это форма, умеет SQL-запросы, фильтры, сортировку, возвращает значения БД findColumn() getString()
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

bk

///осваивать и зазубрить эту чертову объектную модель
Если сам Питоньяк пишет, что не всегда понимает какой сейчас перед ним объект, то уж простым смертным...
Тут что интересно, когда вы по событию Grid Нажатие клавиши мыши получаете объект GridControl (где, в частности, есть метод getCurrentColumnPosition), а потом по маршруту getModel().getParent() переходите в форму, где этот Grid собственно содержится, то из этой формы обратно в Grid я например не нашел способа вернуться. Самое большое, что получилось: из формы по маршруту getControlModel() получить некий объект уже GridControlModel и хотя в нем есть доступ к столбцам, но явно видно, что совершенно другие там свойства-методы и нет того же getCurrentColumnPosition. Способа как попасть из формы в Grid я так и не нашел и мне совершенно не понятно в чем тут дело. Собственно эту задачу я для себя и хотел решить, т.к. у Вас условие было: по событию После смены записи (т.е. в форме).

economist

https://forum.openoffice.org/en/forum/viewtopic.php?f=39&t=38725#p177967

Мне кажется тут победили возврат к Grid из формы (но не уверен). Видимо и с этим придется разобраться, ведь для того чтобы отображать в одном ODT-файле Grid-данные из разных баз данных, что неизбежно и насущно необходимо (например TXT + dbf + SQLite) - их придётся размещать на разных Forms, а значит "восходящее" движение пригодится.

Использование Форм и Grids во Writer в кач-ве печатаемых частей автоматизируемых офисных документов позволит, на мой взгляд, предельно автоматизировать их единственно правильное заполнение и вшить логику бизнес-процесса, которая, как ни крути, всегда основана на данных из БД и ограничениях "момента", более известных как "ЦУ руководства".

Это в каком-то смысле новая парадигма разработки: не монструозная EDM-система управляет шаблонными документами, а наоборот:  "замакросенные" всезнающие документы с формами внутри - "кладут в простую EDM-базу" свои события и статусы, из неё же черпая лишь нумераторы и статистику.

Нынешние пользователи - до полусмерти напуганы непрекращаемой новацией, кайдзеном, бережливым производством и гнетущими их CRM/ERP/EDM-системами, которые нихрена не умеют "из коробки", но ежедневно "сосут" из них кучу данных ручного ввода, большинство которых, скорее всего, никому и никогда не понадобятся.

Поэтому вся работа должна начинаться с Ctrl+N, буквально с чистого листа, а далее все контролы появятся сами - из Автотекста, из скрытых разделов Автотекста и по событиям на основе данных из БД. Обязательно поделюсь на Форуме, что получилось в итоге (если получится что-либо вообще).
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

economist

Итоговое решение с комментами: 

Sub getNumSelectionGridColumnAndCellValue(ev)
' назначен на Св-ва Элемента управления Таблица/GRID - События - Нажатие клавиши мыши
oForm = ev.Source.Model.Parent ' получили Форму
nCol = ev.Source.CurrentColumnPosition() ' узнали номер активного столбца Таблицы
NamedCol = oForm.findColumn("материал") ' задали нужный столбец и узнали его номер
' если номера активного и нужного столбцов не совпали, значит юзер щелкнул "мимо", а это
' может означать что он просто листает Grid в поисках нужного. Для readonly TXT БД это как
' снятый чекбокс на строке (чекбоксы в TXT недоступны). Если совпали - значит поставили.   
cValue = oForm.getString(NamedCol) ' узнали значение нужного столбца активной строки Таблицы
End Sub
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...