Вход | Регистрация

1С:Предприятие ::

Метки:

Вычисление формулы 2

Я
   Diter
 
13.01.05 - 09:12
Доброго всем дня.
Не так давно на форуме пробегала ветка по поводу программного вычисления формулы. Было предложено решение через Шаблон
типа
Результат=Число(Шаблон("[ТекстФормулы]"))
Так вот это не работает. Код самый простой
Процедура Сформировать() 
    Результат=Число(Шаблон("[ТекстФормулы]"));
    Сообщить(Результат);
КонецПроцедуры
"ТекстФормулы" - реквизит формы - поле ввода строки вида "(3+2)/2".
Я впервые столкнулся с "Шаблоном" и наверняка не знаю каких то особенностей использования. Буду благодарен за подсказку.
 
  Рекламное место пустует
   GrayT
 
1 - 13.01.05 - 09:36
   Rovan
 
2 - 13.01.05 - 09:40
(0) Я в табло написал Шаблон("[2*3+2]") , результат = 8
   Diter
 
3 - 13.01.05 - 09:41
(2) Я так тоже умею. А ты напиши так как в коде и увидишь чего будет.
   GrayT
 
4 - 13.01.05 - 09:43
("["+ТекстФормулы+"]")
   Ёжик в тумане
 
5 - 13.01.05 - 09:45
Основной минус такого метода - ошибка при выполнении формулы в шаблоне не вызовет исключительную ситуацию и не может быть обработана конструкциями Попытка/Исключение
   Diter
 
6 - 13.01.05 - 09:47
(4) Огромное спасибо. Всё работает
   Diter
 
7 - 13.01.05 - 09:50
(5) Эту ситуацию я раньше обрабатываю
Код упрощён до безобразия.
На самом деле такая фишка - прикручиваю к своему обменнику блок соответствия для обмена данными между разными базами. Естественно есть масса реквизитов документов и справочников в базе-приёмнике, которые не имеют аналогов в базе-отправителе. Придумал два варианта их заполнения - "по умолчанию" и "формула". Во втором случае (только для числовых реквизитов) юзер может сам задать формулу вычисления такого поля исходя из реквизитов объекта (документ или справочник). Вот такая фигня.
   GrayT
 
8 - 13.01.05 - 09:54
(5)А формулу через процедру прогонять можно, а вней уже попытки "жалкие" делать
   Rovan
 
9 - 13.01.05 - 10:03
(7) Давай код сюда - смотреть будем.
   Diter
 
10 - 13.01.05 - 10:10
(9) Так всё уже работает. А код процедуры вот (не судите строго)
//*************************************************

Процедура ОбработкаФормулы(Объект,ТекстФормулы,Реквизит)
    
    СписокОперандов=СоздатьОбъект("СписокЗначений");
    СписокОперандов.ДобавитьЗначение("(");
    СписокОперандов.ДобавитьЗначение(")");
    СписокОперандов.ДобавитьЗначение("+");
    СписокОперандов.ДобавитьЗначение("-");
    СписокОперандов.ДобавитьЗначение("/");
    СписокОперандов.ДобавитьЗначение("*");
    
    ТаблицаОперации=СоздатьОбъект("ТаблицаЗначений");
    Флаг=0; 
    Колонка=0;
    ТекстФормулыПром=ТекстФормулы; 
    НомерСимвола=1;
    Пока НомерСимвола<=СтрДлина(ТекстФормулыПром) Цикл
        Символ=Сред(ТекстФормулыПром,НомерСимвола,1);
        Если СписокОперандов.Принадлежит(Символ)=1 Тогда
            Если НомерСимвола=1 Тогда
                Сообщить("Ошибка в формуле при вычислении значения реквизита "+Реквизит+" в объекте "+Строка(Объект));
                СтатусВозврата(0);
                Возврат;
            КонецЕсли;
           // всё что до этого - реквизит или число

            Если Флаг=0 Тогда
               // самая первая колонка - нужно создать первую строку

                Колонка=Колонка+1;
                ТаблицаОперации.НоваяКолонка("_"+Колонка);
                ТаблицаОперации.НоваяСтрока();
                ТаблицаОперации.УстановитьЗначение(1,"_"+Колонка,Сред(ТекстФормулыПром,1,НомерСимвола-1));
                Колонка=Колонка+1;
                ТаблицаОперации.НоваяКолонка("_"+Колонка);
                ТаблицаОперации.УстановитьЗначение(1,"_"+Колонка,Символ);
                ТекстФормулыПром=Сред(ТекстФормулыПром,НомерСимвола+1); 
                НомерСимвола=1;
                Флаг=1;
            Иначе     
                Колонка=Колонка+1;
                ТаблицаОперации.НоваяКолонка("_"+Колонка);
                ТаблицаОперации.УстановитьЗначение(1,"_"+Колонка,Сред(ТекстФормулыПром,1,НомерСимвола-1));
                Колонка=Колонка+1;
                ТаблицаОперации.НоваяКолонка("_"+Колонка);
                ТаблицаОперации.УстановитьЗначение(1,"_"+Колонка,Символ);
                ТекстФормулыПром=Сред(ТекстФормулыПром,НомерСимвола+1);
                НомерСимвола=1;
            КонецЕсли;
        Иначе
            НомерСимвола=НомерСимвола+1;
        КонецЕсли;    
    КонецЦикла; 
   // дописываем колонку с остатком строки формулы после последнего оператора

    Колонка=Колонка+1;
    ТаблицаОперации.НоваяКолонка("_"+Колонка);
    ТаблицаОперации.УстановитьЗначение(1,"_"+Колонка,ТекстФормулыПром);
    ТаблицаОперации.НоваяСтрока();
    Колонка=1;
    Пока Колонка<=ТаблицаОперации.КоличествоКолонок() Цикл
        Значение=ТаблицаОперации.ПолучитьЗначение(1,Колонка);
        Если СписокОперандов.Принадлежит(Значение)=0 Тогда
            Если Число(Значение)=0 Тогда
               // опа - реквизит        

                Попытка
                    ЗначениеРеквизита=Объект.ПолучитьАтрибут(Значение);
                    ТаблицаОперации.УстановитьЗначение(2,Колонка,ЗначениеРеквизита);
                Исключение
                    Сообщить("Ошибка в формуле при вычислении значения реквизита "+Реквизит+" в объекте "+Строка(Объект));
                    СтатусВозврата(0);
                    Возврат;
                КонецПопытки;    
            Иначе 
               // число

                ТаблицаОперации.УстановитьЗначение(2,Колонка,Число(Значение));
            КонецЕсли;    
        Иначе     
            ТаблицаОперации.УстановитьЗначение(2,Колонка,Значение);
        КонецЕсли; 
        Колонка=Колонка+1;
    КонецЦикла;
    Колонка=1; 
    СтрокаВыражения="";
    Пока Колонка<=ТаблицаОперации.КоличествоКолонок() Цикл
        СтрокаВыражения=СтрокаВыражения+ТаблицаОперации.ПолучитьЗначение(2,Колонка);   
        Колонка=Колонка+1;
    КонецЦикла;                                        
    ЗначениеРеквизита=Число(Шаблон("["+СтрокаВыражения+"]"));
    Объект.УстановитьАтрибут(Реквизит,ЗначениеРеквизита); 
    Объект.Записать();
КонецПроцедуры
//***************************************************
 
 


Список тем форума
Рекламное место пустует   Рекламное место пустует
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство.
Фредерик Брукс-младший
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Ветка сдана в архив. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует