Calc: Как вставить только значения?

Автор eeigor, 30 июля 2022, 17:45

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

eeigor

Выходной диапазон уже заполнен формулами.
Как вставить только значения? Например, вот так:

 oRange.DataArray = oRange.DataArray  'не работает (интересно почему?)

 oRange.DataArray = oRange.getDataArray()  'странно, но работает
 oRange.setDataArray oRange.DataArray  'странно, но работает

Но я предпочитаю свойства, а не методы (геттеры-сеттеры).
 Dim aData():
 aData = oRange.DataArray: oRange.DataArray = aData  'OK

В Excel то, что выделено красным, сработало бы. По идее, и здесь должно, но... требуется промежуточная переменная.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

sokol92

Добрый день!
Продолжаю считать, что наиболее эффективный метод замены в диапазоне ячеек формул на значения - .uno:ConvertFormulaToValue.
Что касается свойства DataArray, то оно помечено в MRI как IGNORED (пока не знаю, что это  :) ):

IGNORED_PROPERTIES = {'ActiveLayer', 'AsProperty', 'ClientMap', 'FontSlant',
    'LayoutSize', 'Modified', 'PropertyToDefault', 'UIConfigurationManager',
    'ParaIsNumberingRestart', 'NumberingLevel', 'NumberingStartValue', 'NumberingStartLevel', 'DataArray', 'FormulaArray', 'Printer', 'Material'}


(фрагмент кода values.py из MRI).
Владимир.

mikekaganski

Размышляя о вопросе в автомобиле, умозрительно я бы заподозрил у красного выражения "детекцию" присвоения самому себе, и ничегонеделание (имя резолвится в один и тот же объект, а получение значения этого объекта - которое бы потребовало вызов геттера - произошло бы только после сравнения "не присваиваю ли я сам себе").
С уважением,
Михаил Каганский

eeigor

#3
Владимир, я внимательно ознакомился с Вашим детальным обзором в Excel в отношении "побочных эффектов" присвоения значений разных типов.
В примере здесь я выбрал последний вариант с промежуточной переменной (вероятно, упомянутый метод uno будет безопасней для всех случаев в целом).

Цитата: mikekaganski от 30 июля 2022, 19:32имя резолвится в один и тот же объект
Меня просто заинтересовал вопрос внутренней работы "резолвера": слева от знака равенства - значение для присвоения (SET), справа от знака равенства - значение для получения (GET). В структурах данных мы не можем присвоить значения напрямую: надо создать промежуточную структуру, инициализировать её и затем присвоить целиком источнику. Но здесь не структура. И, по идее, должно работать. Теоретически между первыми тремя операторами в стартовом сообщении (выделенным красным и двумя последующими) разницы нет. Но происходит какая-то внутренняя "оптимизация", о которой написал Михаил...

Давайте ещё раз посмотрим.
Цитата: eeigor от 30 июля 2022, 17:45
 oRange.DataArray = oRange.DataArray  'не работает (интересно почему?)

 oRange.DataArray = oRange.getDataArray()  'странно, но работает
 oRange.setDataArray oRange.DataArray  'странно, но работает
Строка "красным" (на внутреннем уровне, как я это понимаю): слева вызывает setDataArray, а справа вызывает getDataArray, то есть просто делается по одному дополнительному шагу для преобразования свойств в методы (ведь свойство здесь - это обёртка метода, надо только соответствующий метод вызывать, исходя из позиции свойства по отношению к знаку присваивания):
 oRange.setDataArray oRange.getDataArray()
Именно этот вариант я не испытывал, считая его идентичным "красному". Тест: работает!

А в чём разница, Михаил? Что "потеряли" разработчики, пока "обёртывали" или оптимизировали?..
ИМХО, вызов свойством-обёрткой соответствующего ему метода в "красном" варианте не обеспечивается должным образом. "Глубинная" ошибка. :)  Могу ошибаться.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

mikekaganski

#4
Цитата: eeigor от 31 июля 2022, 06:18А в чём разница, Михаил?

Присваивание (=)
a=b
1. Find name a
2. Find name b
3. Break if a is b
4. Obtain the value of b (using whatever magic), and assign to a (using whatever magic)


Обратите внимание, что для
Цитата: eeigor от 31 июля 2022, 06:18oRange.setDataArray oRange.getDataArray()
вообще присваивание не происходит, программист запросил вызов процедуры.

Для
Цитата: eeigor от 30 июля 2022, 17:45oRange.DataArray = oRange.getDataArray()  'странно, но работает
a - это переменная oRange.DataArray (которая внутри для получения или присвоения внутри использует методы, но это уже детали реализации переменной), а b - это метод, который по случайности оказался тем же самым, который использовался бы для получения значения переменной oRange.DataArray. Это разные объекты.

А для
Цитата: eeigor от 30 июля 2022, 17:45oRange.DataArray = oRange.DataArray  'не работает (интересно почему?)
a и b - обе являются одной и той же переменной oRange.DataArray.

Обратите внимание: переменная и её значение - разные сущности для Basic.
С уважением,
Михаил Каганский

eeigor

#5
Цитата: mikekaganski от 31 июля 2022, 09:21вообще присваивание не происходит, программист запросил вызов процедуры.
Михаил, спасибо за разъяснения. Я всё понял (здесь и до конца Вашего сообщения).
Значит, в Excel значения вызовов присваиваются разным объектам (без оптимизации памяти).
Однако в этой конструкции (красной) существенным моментом является расположение вызова метода по отношению к знаку присваивания.
Или Вы не согласны?

Edit: С другой стороны, операция с DataArray - это частный случай для частной задачи. Распространять это на всё остальное (с ущербом для памяти) было бы глупо.
Почему в Excel так? Впрочем, я не пробовал, а только предположил (из прежнего опыта). Не уверен, что вывод был абсолютно чистым...
Я поступил верно, использовав промежуточную переменную. То есть явно сообщил, что мне надо.

Ещё раз спасибо. Тема была полезной для меня.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

mikekaganski

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

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

eeigor

#7
Цитата: mikekaganski от 31 июля 2022, 13:06можно рассмотреть вариант совсем отказаться от этой оптимизации
Скорее, нет. Python, к примеру, тут так оптимизирует, что иногда возникают "неожиданности" с пониманием.
Просто теперь я лучше понимаю свой код.

Edit:
Владимир, в моём примере, думается, вызов uno-метода не требуется, поскольку метод getDataArray() уже выполнил всю работу. А с присвоением мы разобрались.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

sokol92

Как говорил старина Карл: Практика - критерий истины.  :)

В прилагаемом файле измеряется скорость замены формул на значения в диапазоне из 1 000 000 ячеек.
На моей конфигурации 1 сек. для команды ".uno:ConvertFormulaToValue" и 6 сек. для setDataArray. Оценки (на мой взгляд): "отлично" и "хорошо".
Владимир.

sokol92

Цитата: mikekaganski от 31 июля 2022, 13:06С другой стороны, простые переменные будут иметь минимальный оверхэд - можно рассмотреть вариант совсем отказаться от этой оптимизации.

Поддерживаю.

Михаил, спасибо за разъяснения!
Владимир.

eeigor

Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community