:: Visual Foxpro, Foxpro for DOS
Заменить нули на пробелы в выходной форме FPD 2.6
Simple777
Автор

Сообщений: 33855
Дата регистрации: 05.11.2006
Положим, в mytable.dbf есть числовые и символьные поля. В отчете выводится содержимое записей.
Одно из полей имеет формат myfield (N,11,4)

Нужно обеспечить следующее при формировании отчета:

Значение         Формат вывода

myfield=10      10.00
myfield=10.1    10.10
myfield=10.11   10.11
myfield=10.111  10.111
myfield=10.1111 10.1111

Иными словами, выводить не менее 2 знаков после запятой, и при этом заменять нули справа от запятой на пробелы, если 3 и/или 4-й знак после запятой содержит нули.

Решение "в лоб", конечно, мне понятно. Даже не буду его приводить ввиду его очевидной "топорности".

А какие есть "нетопорные" варианты?



Исправлено 4 раз(а). Последнее : Simple777, 28.03.18 10:54
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
ry

Сообщений: 2113
Дата регистрации: 24.09.2007
Нетопорных не знаю, а топорных может быть сколько угодно. Навскидку:
? Transform(myfield,"99999999.99")+Strtran(Transform(mod(myfield*100,Int(myfield*100))*100),"0","")
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
Simple777
Автор

Сообщений: 33855
Дата регистрации: 05.11.2006
Нули справа надо не подавить, а заменить пробелами.

Из "топорных вариантов". Когда-то написал UDF-функцию, возвращающую символьную строку нужного вида. Проверялось, будет ли число одинаковым при округлении до двух, трех и четырех знаков после запятой. В зависимости от результата выводилось определенное число знаков после запятой.

Думается, что должен быть способ попроще.



Исправлено 2 раз(а). Последнее : Simple777, 28.03.18 12:27
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
ry

Сообщений: 2113
Дата регистрации: 24.09.2007
Simple777
Нули справа надо не подавить, а заменить пробелами.
Да хоть звездочками, что мешает в приведенном варианте? Но на самом деле он не годится для чисел вида 10.1101, поэтому все равно надо "допиливать". Скорее всего, элегантного решения не существует (но не буду категоричен в силу не очень хорошего знания инструментов форматирования).
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
akvvohinc

Сообщений: 4219
Откуда: Москва
Дата регистрации: 11.11.2008
Simple777
Решение "в лоб", конечно, мне понятно. Даже не буду его приводить ввиду его очевидной "топорности".

Все в мире относительно.
Поэтому стоит привести свое решение, которое ты желаешь улучшить.

Но главное надо озвучить критерии - новое решение должно быть более коротким (более элегантное), или быстрее работать, или не содержать UDF, что-то еще, или все вместе взятое?
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
Simple777
Автор

Сообщений: 33855
Дата регистрации: 05.11.2006
Ну, из чего я исходил. Все мои UDF-функции, которые я тут приводил, были громоздкими. При обсуждении выяснялось, что многое можно сделать значительно проще. Вот и подумал, что могу опять пользоваться своей неоптимальной UDF-функцией. Сейчас нет функции под рукой (со смарта пишу), но суть в том, что передается число и проверяется при помощи ROUND(), сколько есть значащих цифр после запятой. В качестве параметра передается число и максимально возможное число знаков после запятой. Возвращается числовая переменная, - количество значащих цифр после запятой.

Можно иначе сформулировать вопрос: Как узнать, сколько значащих цифр после запятой содержит число?



Исправлено 2 раз(а). Последнее : Simple777, 28.03.18 18:42
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Смотря какое число... В полях dbf-ов, тем паче в FPD хранятся не числа, а их строковый вид - и там всё вполне себе "чётко и однозначно", а вот в памяти (даже в FPD, насколько я в курсе) уже совсем не такое чёткое и однозначное (или, по простому говоря, "красивое") число находится.
А чтобы не сводить с ума фоксовиков, там ещё и нехилая логика по "украшению" и автоматическому округлению чисел прикручена. Во многих других языках этого нет, там программист сразу же сталкивается с "правдой жизни" - в фоксе, бывает лет через 20 вполне себе успешной работы, внезапно осознаёт что то как он до того считал - было в принципе ошибочно
Вот как ты думаешь, сколько десятичных знаков у числа полученного в результате вычисления (0.1+0.2), и равняется ли оно числу 0.3
Так что смысл есть лишь в том, чтобы сделать из числа строку - при этом УЖЕ применив то или иное округление (скажем, тупо задав форматную маску с 4-мя символами после десятичной точки - это тоже своего рода округление/отсечение). А потом просто отрезать "правые" нули (в твоём случае из подстроки RIGHT (,2)) - в 9 фоксе для этого подошёл бы RTRIM, в FPD - не в курсе как более эффективно это делать, наверное только CHRTRAN(), RTRIM(), обратный CHRTRAN() - потом всё это хозяйство снова склеить и дополнить до требуемого размера пробелами.
Для убирания всего 2 символов это, конечно, неэффективно. Проще пару IF-ов применить. Но для заранее неизвестного числа символов - наверное лучше всё же более универсальный алгоритм...
Т.е. весь смысл в том, что манипуляции проводятся уже над строкой, а не самим исходным числом - иначе велик риск попасть на ту или иную "ошибку округления".


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
Simple777
Автор

Сообщений: 33855
Дата регистрации: 05.11.2006
Вот ведь говорил же заказчику - зачем им такая фигня? Говорят - так хочет вышестоящая организация - им так, видите ли, удобнее проверять. :doom: \m/

То есть никому такого не надо в этой сфере, а вот этим вдруг надо. Да поставлю свою функцию и дополню PADR-ом() до нужной длины. Но зачем вот такая бессмысленная фигня? :al:
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Как-то так, наверное, делал бы. ХЗ всё ли из этого работает в FPD, и не отличается ли там поведение STR для всяких "предельных случаев".


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
Simple777
Автор

Сообщений: 33855
Дата регистрации: 05.11.2006
Ну, запись числа в формате E - этого в моем частном случае точно не будет. (N,11,4) вполне "закрывает" даже итоговые суммы.

Надо будет проверить, как будет работать предложенная функция в FPD. Опций local, там нет, и такие длинные имена переменных не поддерживаются. А остальное должно работать.

Спасибо!
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
Crispy

Сообщений: 18571
Дата регистрации: 16.05.2005
Да проще ж можно.
Всего лишь используя заведомо работающие в FPD функции IIF() и STUFF().
Как-то так:
* тестовая таблица:
CREATE CURSOR tmp (myfield n(11,4))
INSERT INTO tmp VALUES (10)
INSERT INTO tmp VALUES (10.1)
INSERT INTO tmp VALUES (10.11)
INSERT INTO tmp VALUES (10.111)
INSERT INTO tmp VALUES (10.1111)
SET TALK OFF
CLEAR
* проверяем, как выводится:
SCAN
n = STR(myfield,11,4)
? IIF(RIGHT(n,2)='00',STUFF(n,10,2,' '),IIF(RIGHT(n,1)='0',STUFF(n,11,1,' '),n))
ENDSCAN

Можно разумеется эту строку вывести и в отдельную процедуру с параметром и возвратом:
PROCEDURE vyvod
PARAMETER fld
n = STR(fld,11,4)
RETURN IIF(RIGHT(n,2)='00',STUFF(n,10,2,' '),IIF(RIGHT(n,1)='0',STUFF(n,11,1,' '),n))

Тогда вывод где-то по тексту программы будет вызовом данном процедуры, возвращающей строку нужного формата:
SCAN
? vyvod(myfield)
ENDSCAN

[sm128]


------------------
В действительности все иначе, чем на самом деле.
                                      (Антуан де Сент-Экзюпери)




Исправлено 1 раз(а). Последнее : Crispy, 29.03.18 10:31
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
Simple777
Автор

Сообщений: 33855
Дата регистрации: 05.11.2006
Вот такого простого я и ожидал. :bi:

Правда, сейчас проверить не могу. Но видать должно работать.
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Конечно можно проще - ты ведь по сути частный случай (для параметров 11,4,2) моего варианта и привёл - только со STUFF вместо LEFT+SPACE. Ну и без тех самых защит что я понатыкал на всякий случай...

И почему это вы считаете что защиты от "странных" чисел (даже без явных записей в E-нотации) не нужно - для меня большая загадка.
INSERT INTO tmp VALUES (1234567.1)
INSERT INTO tmp VALUES (1234567890)
INSERT INTO tmp VALUES (12345678900)
Нет, оно, конечно, можно и "забить" - ну дадут тебе зарплаты вместо 100 тыщ всего 100 рублей - это ж ерунда, не так ли


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
Божья_коровка

Сообщений: 25731
Дата регистрации: 23.08.2001
Igor Korolyov
Нет, оно, конечно, можно и "забить" - ну дадут тебе зарплаты вместо 100 тыщ всего 100 рублей - это ж ерунда, не так ли
Деноминация, однако


------------------
Жись, она как зёбра, полоса белая, полоса черная, а мне всегда задница достается...
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
akvvohinc

Сообщений: 4219
Откуда: Москва
Дата регистрации: 11.11.2008
Igor Korolyov
Нет, оно, конечно, можно и "забить" - ну дадут тебе зарплаты вместо 100 тыщ всего 100 рублей - это ж ерунда, не так ли

Нет, в варианте Crispy такого не случится, так как STR() при выводе "большого" числа обрежет не старшие разряды, а младшие.

Но чтобы и этого не произошло достаточно заменить 11 на большее значение. Тогда и Е-числа в пределах фоксовской точности будут нормально выводиться:
#DEFINE MAXLEN 30
n = STR(fld,MAXLEN,4)
RETURN IIF(RIGHT(n,2)='00',STUFF(n,MAXLEN-1,2,' '),IIF(RIGHT(n,1)='0',STUFF(n,MAXLEN,1,' '),n))
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
Simple777
Автор

Сообщений: 33855
Дата регистрации: 05.11.2006
Конечно, универсальная UDF-функция должна проверять всё - тип переданной переменной, форму представления и т.п. И всякие проверки должны быть.

В моем же частном случае, во-первых, надо реализовать совершенно идиотское требование. Во-вторых, для этого самого MYFIELD предусмотрен шаблон ввода PICTURE '999999.9999'

У юзера просто нет никакого способа ввести что-либо иное, кроме того, что разрешено в шаблоне. Поэтому простое частное решение по замене последних двух нулей вполне сгодится. Можно это сделать и через IIF, и через UDF. Предложенные варианты выглядят более эффективными по сравнению с моей UDF-функцией.

Так что цель достигнута. Завтра или послезавтра буду делать корректировку в 25 модулях. Поскольку требование явно идиотское, пришлось вводить еще настроечный параметр, чтобы у всех остальных работало "как раньше".
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Не в курсе за FPD (лень опять искать/ставить - пусть вон симпла тренируется, ему проще), а для VFP я как раз привел 3 записи в его пример, показывающие недостаток такой функции. STR вовсе не обязан выводить ровнёхонько указанное число символов после десятичной точки. E-нотация это один пример, просто "широкое/неформатное" число - другой. Твой вариант, конечно решит часть задачи - за счёт возврата заведомо более длинного выражения.

А ты его впиши в отведенные 11 символов то - и без потерь Сколько ещё буковок кода потребуется?


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
akvvohinc

Сообщений: 4219
Откуда: Москва
Дата регистрации: 11.11.2008
Igor Korolyov
А ты его впиши в отведенные 11 символов то - и без потерь Сколько ещё буковок кода потребуется?

Что-то в постановке задачи я ничего про "отведенные 11 символов" не увидел.

Единственное требование:
Simple777
Иными словами, выводить не менее 2 знаков после запятой, и при этом заменять нули справа от запятой на пробелы, если 3 и/или 4-й знак после запятой содержит нули.
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
of63

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
> Что-то в постановке задачи я ничего про "отведенные 11 символов" не увидел.
- ТС хочет изобразить на длине 11 символов сумму с копейками
- произвольно большую сумму изобразить - это невозможно
- ТС упомянул, и другие авторы, что можно ПРИМЕРНО показать сумму, но будут потеряны знаки после запятой (копейки), или возникнет E-представление. В любом случае бухгалтерская точность будет потеряна. 11 символов в принципе недостаточно при современных суммах. STR(14,2) рулит, но если вы работаете только с местными бюджетами. Сами понимаете точность фокса - 9.5 значащих десятичных символа (если использовать поле-число-количество Integer), рублевая сумма - Double - 13-14-15 достоверных десятичных знаков). В запасе есть максимальное - "денежное", тип "Y" истиное 8-байтовое число- сумма с 3мя знаками после запятой, фокс об этом озаботится, об округлении до 3х знаков после ЗПТ...)



Исправлено 4 раз(а). Последнее : of63, 30.03.18 00:35
Ratings: 0 negative/0 positive
Re: Заменить нули на пробелы в выходной форме FPD 2.6
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
В FPD нет ни Integer ни Currency (там, кстати, 4 знака после десятичной точки).
Естественно что про ограничение размера я сам "додумал" - только чтобы показать на ещё один изъян предложенного способа. STR всё же достаточно "умная" функция, и пытается адекватно показать любое число, даже если оно с большим трудом "вмещается" в отведенные размеры. Я постарался по максимуму сохранить это его полезное свойство.


------------------
WBR, Igor
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 15 (Гостей: 15)

© 2000-2024 Fox Club 
Яндекс.Метрика