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

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

17 Май 2022, 03:42 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

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

Сообщений: 698


« Стартовое сообщение: 8 Декабрь 2021, 11:31 »

Вчера поставил обновление LO 7.2.4.1

После этого часть формул, создаваемых макросом в листе calc, стали выдавать ошибку.
Причём как-то странно - в одних случаях формула продолжает работать с других нет.

Вот такую формулу создаёт макрос (oVK = 5 (intager)):
Код:
oSheet.getCellByPosition(14, oRow).setFormula("=C701*" & oVK/100)
Она перестала работать.

Нашёл такой выход, как всегда обходной:
Код:
oSheet.getCellByPosition(14, oRow).setFormula("=C701*" & oVK & "/100")

Эта формула прекращает работать в тех случаях если используется формат ячейки C701 с разделителями разрядов тысяч и если это значение больше тысячи (т.е. появляется пробел между тысячами и пр.). Пока число меньше тысячи формула работает. Появляется пробел разделителя - появляется ошибка "=#ИМЯ".

Регресс, однако.
Записан
mikekaganski
Гуру
*******
Offline Offline

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


« Ответ #1: 8 Декабрь 2021, 12:19 »

Это не регресс, а прогресс. Конкретно - это исправление бага 97983, где раньше простое приведение числа к строке не использовало параметры локали.

Раньше было так:

Код:
  dim s as string
  dim d as double
  d = 1.5
  s = d ' s = "1.5" независимо от текущей локали!!!
  d = s ' d = 1.5 в локали en-US, и d = 1 в локали ru-RU, потому что в последней превращение строки в число правильно использовало локаль!

Теперь:

Код:
  dim s as string
  dim d as double
  d = 1.5
  s = d ' s = "1.5" в локали en-US, и s = "1,5" в локали ru-RU
  d = s ' d = 1.5

При этом, как и раньше, локаль-независимые преобразования строк в числа и обратно должны производиться с помощью функциq Val/Str. См. руководство по Basic.

А setFormula как раз и устанавливает локаль-независимую формулу, и поэтому все числовые литералы там должны использовать точку.

Код:
oSheet.getCellByPosition(14, oRow).setFormula("=C701*" & Str(oVK/100))
Записан

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

Сообщений: 698


« Ответ #2: 8 Декабрь 2021, 12:53 »

Интересненький "прогресс".
То, что были проблемы с локалями это факт. Из-за неё мне часто приходится в своих макросах испрользовать подмены типа
Код:
var = replace(var1,",",".")

Если это исправлено, то это прекрасно.

Однако, странное дело таки с этим "прогрессом".
Простая матемематическая формула - oVK/100, перестала работать.
Причём действительно в совокупности с разделителями тысяч.
Засомневался в своей версии про разделители, ведь исправление "oVK/100" на "oVK & "/100"" дало положительный результат, а оно меняет разделители дробной части, а не тысячные.
В общем, попробовал проверить так:
Код:
Dim dVK#
dVK = oVK/100
oSheet.getCellByPosition(14, oRow).setFormula("=C701*" & dVK)
Не алё. Результат - ошибка.

Если после формирования страницы calc вручную обновить ссылку на ячейку C701, при первичном варианте формулы (т.е. - ""=C701*" & oVK/100"), то ошибка уходит.

Вариант с "Str(oVK/100)" работает.

Однако, странное "улучшение", с усложнением.

Нужно ещё проверять не испортились ли формулы в других местах программы. Пока выявил в одном месте, но из же гораздо больше.
« Последнее редактирование: 8 Декабрь 2021, 12:57 от Kadet » Записан
mikekaganski
Гуру
*******
Offline Offline

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


« Ответ #3: 8 Декабрь 2021, 13:00 »

В общем, попробовал проверить так:

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

То, что были проблемы с локалями это факт.

Но то, что Вы привели как "проблемы с локалями", является просто неумением работать с ними.
« Последнее редактирование: 8 Декабрь 2021, 13:01 от mikekaganski » Записан

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

Сообщений: 698


« Ответ #4: 8 Декабрь 2021, 13:15 »

"Правильный вариант", насколько я понимаю, был проверен и подтверждён, и даже отзыв об этом описан. Не так?
Просто ДО появления "правильного" варианта были проведены тесты других вариантов. Что и описано.

Однако, что скрывается за:
является просто неумением работать с ними
?

Когда я беру данные из ячейки calc, где по локали дробное число представляется через запятую, и пытаюсь его засунуть в БД, у которой по умолчанию и неизменно разделитель дробной части является точка и ничто другое, в итоге получаю ошибку, пока не проведу replace переменной с переводом её в Str.
В чём "неумение"?
« Последнее редактирование: 8 Декабрь 2021, 13:17 от Kadet » Записан
mikekaganski
Гуру
*******
Offline Offline

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


« Ответ #5: 8 Декабрь 2021, 13:18 »

Я уже описал: для локаль-зависимых преобразований используются одни методы, для независимых - другие. Даже ссылку дал на документацию. Использование replace для этого неправильно.
Записан

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

Сообщений: 698


« Ответ #6: 8 Декабрь 2021, 13:21 »

Да даже любое математическое получение дробного числа типа doeble в макросе, допустим как результат математической функции, тоже приходится прогонять через replace чтобы подать его в SQL запрос.
Записан
Kadet
Форумчанин
***
Offline Offline

Сообщений: 698


« Ответ #7: 8 Декабрь 2021, 13:22 »

...зависимых преобразований...
...независимых...
Для меня это абракадабра. Не понимаю о чём речь. Со ссылкой и без неё - не понимаю. Тем более в английской версии.
« Последнее редактирование: 8 Декабрь 2021, 13:24 от Kadet » Записан
Kadet
Форумчанин
***
Offline Offline

Сообщений: 698


« Ответ #8: 8 Декабрь 2021, 13:41 »

Чего уж тут понимать?
Раньше функция Str в принципе не работала.
Поэтому всеми силами старался её избегать или обходить с финдиперсами. Много крови попила.
Зато простая банальная "неправильная" математика внутри формулы, как -то (""=C701*" & oVK/100") - работала и кушать не просила.

А теперь... всё наоборот.
Теперь, однако, без Str уже не обойтись.
« Последнее редактирование: 8 Декабрь 2021, 13:49 от Kadet » Записан
mikekaganski
Гуру
*******
Offline Offline

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


« Ответ #9: 8 Декабрь 2021, 14:03 »

Когда Вы работаете с числами и строками, первое, что необходимо понять - это что число может быть представлено разными строками, а разные строки, представляющие одно и то же число, могут быть по-разному восприняты в разных случаях. Это связано с богатой историей человечества, письменности, математической записи и других увлекательных вещей. В принципе это всё зависит от локали (то есть от соглашений по представлению данных, принятых в данной местности или в данной ситуации).

Понимание этого приводит нас к понятию текущей локали. Обычно это то, что представляется "обычным/нормальным" простому пользователю Вашей программы: например, использование запятой для разделения дробной части в России. В Basic стандартные преобразования все задуманы использующими именно текущую локаль - то есть все стандартные преобразования должны в России считать дроби отделяющимися запятой.

Однако при программировании имеется множество вещей, которые не должны зависеть от локали. Например, если Вы формируете формулы и будете их писать для Вашей русской локали, с использованием русских названий функций и т.п., то программа не будет работать в других локалях. Поэтому программист должен думать о том, в каком месте программы у него данные в текущей локали, а в каком - должны быть независимы от текущей локали. Это основы, без этого понимания всегда возникают проблемы.

В ЛО был баг, что стандартное преобразование числа в текст всегда использовало "стандартную" локаль en-US, а стандартное преобразование текста в число - текущую локаль. Это было несоответствие документации и дизайну. Это и было исправлено. А для приобразования любого числа в стандартный вид (независимо от локали в строку с использованием точки для разделения целой и дробной частей) - всегда были функции Str и Val. Надо преобразовать строку, введённую пользователем, в число - используем стандартное преобразование (просто присваиваем строку числовой переменной). Надо взять число из базы данных, где числа в стандартной форме - используем Val(s). Надо число показать пользователю - используем стандартное преобразование (например, просто передаём число в MsgBox), что даст привычный для пользователя вид. Надо число засунуть в формулу Calc, где используется стандартный вид - используем Str(n).

Ну и всегда для преобразований с использованием локали (то есть вместо стандартных преобразований) можно было использовать функции CStr/CInt/CDbl/...

То, что Вы полагались на нестандартное, ошибочное поведение в одних местах, и страдали от того же самого в других - это и был баг, который полностью рушил логику  преобразований. Исправление ничего не усложнило. Если бы Вы использовали Str/Val/CStr/CDbl... везде, где данные преобразуются между типами (число-строка), Вы даже не заметили бы ничего.

А использовать replace для того, что Вы делаете - нельзя, потому, например, что в некоторых локалях запятая - это разделитель тысяч.
« Последнее редактирование: 8 Декабрь 2021, 14:06 от mikekaganski » Записан

С уважением,
Михаил Каганский
mikekaganski
Гуру
*******
Offline Offline

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


« Ответ #10: 8 Декабрь 2021, 14:04 »

Раньше функция Str в принципе не работала

Это когда она не работала?
Записан

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

Сообщений: 698


« Ответ #11: 8 Декабрь 2021, 14:47 »

Это когда она не работала?
Это когда при d=1,5 она делалось d = 1.
А зачастую просто давала ошибку. Приходилось от неё избавляться. И началось это не так давно.
В общем пришлось выискивать и проверять все входы этой функции.
В общем, с какого-то времени я стал избегать и даже побаиваться этой Str.

А теперь - всё наоборот.

Спасибо за лекцию, но всё это понятно и известно. Мне в принципе не понятно какие математические функции могут быть независимы от локали. Разве что 1+1.

Мне больше не понятно почему перестала работать вариация "на свободную тему" - "=C701*" & oVK/100. По сути я передаю ячейке строку "=C701* плюс числовое дробное значение - (допустим = 0,05), как результат вычисления - oVK/100. И я не заморачивался с переводом в Str и с локалями. И транслятор Bacic сам всё это переводил в удобный для себя формат... и это работало.
И теперь, почему-то, транслятору нужно "чётко говорить" - "переведи в Str", хотя раньше это было излишним.
« Последнее редактирование: 8 Декабрь 2021, 14:53 от Kadet » Записан
mikekaganski
Гуру
*******
Offline Offline

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


« Ответ #12: 8 Декабрь 2021, 14:57 »

Ох.

Вы не понимаете, чем число 0,1 отличается от строки "0,1"?
Записан

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

Сообщений: 698


« Ответ #13: 8 Декабрь 2021, 14:57 »

Если мне не изменяет память, то любое число типа double, при переводе через Str выбивало ошибку. Точно не помню с когда это началось. Возможно с выходом 7-ки, но не буду утверждать.
Почему помню и говорю об этом? Потому что во многих своих SQL-запросах для занесения данных типа double в базу мне постоянно приходилось использовать подобный конструкт:
Код:
Replace(Str(oSheet.getCellByPosition(14, oRow).getValue()), ",", ".")
И таких "приколов" было просто тьма.

А потом, в каокй-то момент всё пришлось переписывать и убирать все упоминания Str, ибо при каждом её упоминании неизменно давало ошибку.
Записан
Kadet
Форумчанин
***
Offline Offline

Сообщений: 698


« Ответ #14: 8 Декабрь 2021, 15:04 »

Вы не понимаете, чем число 0,1 отличается от строки "0,1"?
Понимаю.
Только не понимаю почему раньше транслятор сам переводил число, результат вычисления oVK/100 (т.е. число 0,05), в строку, переводя это в удобный для себя формат (по сути в 0.05 - с точкой), а теперь перестал. И теперь ему для этого потребовались конкретные указания программиста - "Str(oVK/100)"
« Последнее редактирование: 8 Декабрь 2021, 15:10 от Kadet » Записан
Страниц: 1 2 »   Вверх
  Печать  
 
Перейти в:  

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