Как получить имя поименованной ячейки?

Автор Kadet, 26 мая 2021, 07:26

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

Kadet

Добрый день, уважаемые коллеги!
Столкнулся с такой проблемой.
Делаю много поименованных ячеек:
i = 0
j = 0
oDoc = ThisComponent
oSheet = oDoc.Sheets(0)
oNamedRanges = oDoc.NamedRanges
oNamedRanges.addNewByName("CellName", oSheet.getCellByPosition(j, i).AbsoluteName, oSheet.getCellByPosition(j, i).CellAddress, 0)

Обращаться к этим ячейкам и получать данные из них становится легко:
oPole = oSheet.getCellRangeByName("CellName").String

Однако, возникла обратная необходимость. На ячейках стоит листенер, который следит за их изменением. И поэтому есть необходимость получить имя ячейки, в которой произошло изменение.
Никак не могу получить это имя. Подскажите, пожалуйста, решение.

mikekaganski

Перебором. Ячейка может входить в любое число именованных диапазонов.
С уважением,
Михаил Каганский

economist

#2
Имена есть в структуре ThisComponent.NamedRanges Работать с ними в LO - то еще удовольствие.

Адрес ячейки в Листнере - совпадет с активной ячейкой, на Форуме есть готовая функция от @eeigor getActiveCell

В похожей ситуации - отдал под это дело листик, где вывел построчно адреса/имена. Знаю адрес - беру рядом имя и наоборот.

PS Решения наверняка тут: https://forum.openoffice.org/en/forum/viewtopic.php?f=9&t=83753&hilit=get+name+of+cell+namedranges#p389060
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

Kadet

#3
Цитата: mikekaganski от 26 мая 2021, 08:38Перебором. Ячейка может входить в любое число именованных диапазонов.
Перебором не красиво и долго выходит.
Цитата: economist от 26 мая 2021, 09:14Имена есть в структуре ThisComponent.NamedRanges Работать с ними в LO - то еще удовольствие.
Имена нашёл. Структуру нашёл. В листенере ячейку ловлю через oEvent.Source.
Пытался поймать имя занося полученную по Event ячейку в новый Rang. Не получается. Ща поизучаю ссылку. Может что полезное подчерпну.
Спасибо!

economist

Ну и вот "ленивое" решение на VBA, если мы говорим про одиночные имен. ячейки (нужна та же функция getActiveCell)


Option VBASupport 1

Sub ActiveCellName
For Each nm In ActiveWorkbook.Names
ac_adr = mid(getActiveCell(ThisComponent.CurrentController).AbsoluteName,2)
ac_adr = "=" & replace(ac_adr, ".", "!") ' привели к Excel-адресу, настройки LO кмк не влияют 
if ac_adr = nm.RefersTo then msgbox nm.Name ' имя акт яч
Next
End sub

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

Kadet

#5
А вообще, вопрос стоит совсем в другом.
Мне нужно временно сохранить изменяемые данные при переформировании документа.

Вот документ. Проект. В нём есть вариаторы (подчёркнуты красненьким). Они изменяемые. Их можно менять и эти изменения должны использоваться при новом пересчёте. А вот при каждом пересчёте все листы документа (кроме нулевого) удаляются и заново формируются.
И ещё - места у этих вариаторов не фиксированы, а меняются в зависимости от масштабов, от размеров чертежей, параметров объекта и разрешений разных компов и т.д.. Т.е. - по адресу ячеек получать данные с них не получается.

Я придумал именовать эти ячейки и добираться к ним через имена, но тут возник встречный вопрос с листерером.

Может есть какой-нибудь другой, более простой и удобный вариант временно сохранять данные и затем их использовать. И следить за их изменениями?

Kadet

#6
Ну, перебором (по предложенной ссылке) я и сам пробовал. Только не нравится этот метод. Думал, может есть какой-то другой, прямой и более простой способ, которого я не знаю.

economist

Именованные ячейки оптимальны для изменяемых макропараметров без фиксированного A1-адреса.

Другое дело что параметрическое конструирование обычно делают вcё-таки CAD/САПР типа NanoCAD/OpenCAD/EasyCAD/AutoCAD итд. Все они позволяют передать макропараметры ДхШхВ итп скриптами (часто там VBA или Python).
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

Kadet

#8
Цитата: economist от 26 мая 2021, 10:33Другое дело что параметрическое конструирование обычно делают вcё-таки CAD/САПР типа NanoCAD/OpenCAD/EasyCAD/AutoCAD итд. Все они позволяют передать макропараметры ДхШхВ итп скриптами (часто там VBA или Python).
Ну, это конечно, НО... задача не просто сделать проект, а совместить его с БД этих проектов, со статистикой, математикой, ком.предложениями и пр. пр. пр. Именно потому, что моя БД сделана на LO Base я и открывают "новые горизонты" в этой области.

economist

Цитата: Kadet от 26 мая 2021, 10:31не нравится этот метод.

От перебора можно отказаться, если имена ячейкам давать программно и... в виде адреса "_A1" :-)

Перебор сотен имен идет мгновенно, их можно поделить по листам и оптимизировать поиск, почему не использовать готовое и простое решение на том же VBA из #4?  
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

Kadet

Просто, по поводу перебора у меня есть печальный опыт.
В этом же проекте все размеры проставлены с помощью врезок:
'**** Создать ТЕКСТОВЫЙ ФРЕЙМ ***************************************************************
Sub DrawTextField(xDoc, index%, Xpoz&, Ypoz&, lState, width, color&, oKegl, iRotAngle, sName$, tText)
Dim xPage as object, xShape as object, oSheet, oRange, oTCursor, oStart, sText, oText
Dim aPosition As New com.sun.star.awt.Point
Dim TheSize As New com.sun.star.awt.Size
Dim aFrameRect As New com.sun.star.awt.Rectangle
Dim oLineDash As New com.sun.star.drawing.LineDash

xPage = xDoc.DrawPages(index)
If IsNumeric(tText) Then
oSheet = xDoc.sheets(index)
oRange = oSheet.getCellByPosition(100,0)
oRange.NumberFormat = getNumberFormat(xDoc, "# ##0;[RED]-# ##0")
oSheet.getCellByPosition(100,0).Value = tText
sText = oSheet.getCellByPosition(100,0).String
oSheet.getCellByPosition(100,0).String = ""
Else
sText = tText
End If
' Первая линия ********************************
xShape = xDoc.createInstance("com.sun.star.drawing.TextShape")
xShape.LineColor = color
xShape.LineWidth = width
aPosition.X = Xpoz
aPosition.Y = Ypoz
xShape.setPosition(aPosition)
TheSize.width = 100
TheSize.height=100
xShape.setSize(TheSize)
aFrameRect.X = Xpoz
aFrameRect.Y = Ypoz
aFrameRect.width = 100
aFrameRect.height=100
xShape.FrameRect = aFrameRect
' xShape.FillColor = RGB(200, 200, 200)
' xShape.LineTransparence = 0
xShape.FillTransparence = 100
' xShape.LayerID = 0

If sName="" Then
xShape.Name = "Врезка"
Else
xShape.Name = sName
End If
xShape.RotateAngle = iRotAngle
xShape.CornerRadius = 20
xShape.LineStyle = lState

xShape.TextAutoGrowHeight = True
xShape.TextAutoGrowWidth = True
xShape.TextContourFrame = True

xPage.add(xShape)
oText = xShape.getText()
oTCursor = oText.createTextCursor()
oStart = oText.getStart() 'Курсор в начало текста, от него и пляшем
oStart.CharHeight = oKegl

' xShape.TextUpperDistance = 100
xShape.TextLeftDistance = 100
xShape.TextRightDistance = 100
' xShape.TextLowerDistance = 100
' xShape.LineEndCenter = True
xShape.TextHorizontalAdjust = 3
xShape.TextVerticalAdjust = 3
xShape.ParaAdjust = 3

' oStart.ParaTopMargin=100
oStart.ParaLeftMargin=100
oStart.ParaRightMargin=100
' oStart.ParaBottomMargin=100
oStart.ParaAdjust=3
oStart.ParaIsCharacterDistance=True
oStart.ParaIsForbiddenRules=True

oText.insertString(oStart, sText, False )
' xShape.String = sText

End Sub



Все эти врезки тоже поименованы. Однако, в отличие от ячеек calc достучавться к ним по имени нет никакой возможности. getByName - не работает, хотя имена их прекрасно получаются по oTextField.Name. При этом по getByIndex прекрасно достукивается. Поэтому приходится искать перебором.
Если это одиночный перебор, то куда ни шло. А вот когда включаешь сохранение всего проекта, и программа начинает перебирать все размеры перебором каждой врезки - это нечто.
В общем - долго приходится ждать.

economist

Перебор "врезок" (Вставка - Текстовое поле) в Calc на неск. формах, да еще и с наведением красоты - канеш, будет долгим. Надо все минимизировать. 20 готовых врезок - могут вполне быстро обновляться.

Просто вы создали в Calc квази-САПР только ради расчетов, исходные данные для которых лежат в Base, а правильнее было бы упростить, вынеся визуализацию эскизного проекта во что-то другое. Любая девиация задачи - например склад в 2-х уровнях или T/Г-образный, или на большм уклоне - и Calc не справится. Точнее справится, но с трудом. То что уже есть сейчас - круто, и вполне оправдывает трудности, желаю довести продукт до ума, не расстраиваться из-за мелочей, быстрота не нужна, клиент подождет.

Кстати, Все программы для эскизного проектирования, начиная с "кетчупа" SketchUp - делают смету материалов со всеми итогами/м2/м3 итд. Остается проблема раскроя, вот её в "продажной" Base или чем-то еще как раз и решают макросами. Но чаще всего не решают никак.   
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

Kadet

У меня так де была идея использовать для временного сохранения данных глобальную переменную-массив типа - com.sun.star.beans.PropertyValue. Однако, тут возникла та же проблема - по параметру Name обратиться не получается. Опять только перебором.

Kadet

Цитата: economist от 26 мая 2021, 12:45Кстати, Все программы для эскизного проектирования, начиная с "кетчупа" SketchUp - делают смету материалов со всеми итогами/м2/м3 итд. Остается проблема раскроя, вот её в "продажной" Base или чем-то еще как раз и решают макросами. Но чаще всего не решают никак.
Не совсем понял, что за слова вы произносите (с "кетчупа" SketchUp)... Языками не владею... :)))))
Но я разберусь.

Следующий этап будет каркасник, а там без 3-D моделирования и графического конструктора не обойтись. Сейчас уже начинаю обдумывать с какой стороны подбираться к этой работе.

Kadet

Цитата: economist от 26 мая 2021, 12:45То что уже есть сейчас - круто, и вполне оправдывает трудности, желаю довести продукт до ума, не расстраиваться из-за мелочей, быстрота не нужна, клиент подождет.
Спасибо за поддержку.