PDA

Просмотр полной версии : Индийский код в 1-с



Гарольд
10.11.2014, 21:39
Столкнулся намедни, перетряхивая "Рарус" на 1с-7

Программисту нужно было посчитать время работы транспорта в ночное время.
Разобрал алгоритм, вот как то так :)


Цикл по минута от временивыезда до времениприбытия;

Если время(Минута) находится в интервале времени (от 22 вечера до 24 вечера)или(от 0 до 6 утра) то Ночные=Ночные+1; КонецЕсли;
Минута=минута+1;

КонецЦикла;

Не, оно работает (там потом еще прикол в том, что минуты считаются в десятичном формате,сотыми долями и предварительно приводятся к десятичному счислению (типа 100 минут, вероятно дабы не проверять на больше 60)..

Но каким пОтом дается машине пересчет например обработка рейсов гаража с начала года ...процессор на глазах раскаляется :)

Ведь можно было вычислить гораздо проще и без перебора всего времени работы..

Вот пока будут платить за количество строк - будем недоумевать - чего оно так долго считается...:)

ElSonador
10.11.2014, 22:41
Экономия на условиях.

Элегантное решение в своём роде.

Мать Тереза
10.11.2014, 22:47
Долговато будет.
Если отказаться от перебора, то условий больше придется нарисовать. Но они же не будут работать в цикле. Поэтому в итоге меньше сравнений будет.

Гарольд
10.11.2014, 22:57
Экономия на условиях.

Элегантное решение в своём роде.

Ну не знаю! Заменил на НочноеВремя = 8*(ДатаПрибытия - ДатаВыезда) - полные часы ночные.
Ну и 4 условия (Если) на день выезда и приезда, если выехал-приехал ночью и для обсчёта минут. И никаких циклов :)

Мать Тереза
10.11.2014, 23:03
Грубо так:
Если (ВремяДатаНачала не в интервале) и (ВремяДатаКонца не в Интервале) и (ДатаНачала = ДатаКонца) Тогда
Ночные = 0;
ИначеЕсли (ВремяДатаНачала не в Интервале) и (ВремяДатаКонца в Интервала) Тогда
Ночные = ВремяДатаКонца - ВремяДатаНачалаИнтервала;
ИначеЕсли (ВремяДатаНачала в Интервале) и (ВремяДатаКонца не в Интервала) Тогда
Ночные = ВремяДатаКонцаИнтервала - ВремяДатаНачала;
ИначеЕсли (ВремяДатаНачала в Интервале) и (ВремяДатаКонца в Интервала) Тогда
Ночные = ВремяДатаКонца - ВремяДатаНачала;
Иначе
Ночные = 28800;
КонецЕсли;

Ночные = Ночные/3600;

- - - Добавлено - - -

Правда, многосуточные рейсы не учитывала.

ElSonador
10.11.2014, 23:20
Да, как-то так.


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

Гарольд
10.11.2014, 23:35
Я не стал ломать систему целое-часы, дробное-минуты( в путевом листе так заводится время), получилось вот что..

НочныеЧасы = 8*(ДатаВозврата-ДатаВыезда); // Целых суток

// Далее - только день отлёта-день прилёта :)

Если ВремяВыезда < 6 Тогда //Выехал утром
НочныеЧасы=НочныеЧасы+(6 - ВремяВыезда);
Если (ВремяВыезда-Цел(ВремяВыезда) <> 0) Тогда
НочныеЧасы=НочныеЧасы-0.4 ;// корректируем, десятичные минуты после минусовки вылазят в 0.40-0.99
КонецЕсли;
КонецЕсли;
Если ВремяВыезда >=22 Тогда //Выехал вечером
НочныеЧасы=НочныеЧасы+(24 - ВремяВыезда);
Если (ВремяВыезда-Цел(ВремяВыезда) <> 0) Тогда
НочныеЧасы=НочныеЧасы-0.4 ;//минуты 0.40-0.99
КонецЕсли;
Конецесли;

Если ВремяВозврата <=6 Тогда // Приехал утром
НочныеЧасы=НочныеЧасы+(ВремяВозврата-6);
КонецЕсли;
Если ВремяВозврата >22 Тогда
НочныеЧасы=НочныеЧасы+(ВремяВозврата-22); // Приехал ночью
Конецесли;

Если (НочныеЧасы-Цел(НочныеЧасы)) = 0.6 Тогда
// когда минуты выезда=минутам приезда - просчитывает как 0.60 минут = 1 час.
НочныеЧасы=НочныеЧасы+0.4;
КонецЕсли;

//****

Мож и корявенько, но все таки быстрее чем по минутке :)
Многовложенные конструкции ИначеЕсли не очень нравятся... Если можно - стараюсь без них..

Гарольд
05.03.2015, 16:10
Касательно обновления валюты в 1с7.
В исходнике привязка к сайту РБК.
Но там не всегда вовремя обновляют список. Особенно в последнее время..

Сделал свой "Индийский код" по разбору ХТМЛ-кода (вернее, по выкидыванию тегов и добыче цифирок) с сайта ЦБ РФ, мож кому пригодится.. Обновляются только USD и EUR, можно любые другие - код валюты надо указать.
На основе первоначальной обработки ИППКурсыВалютРБК. В принципе можно объединить, брать валюты там и там (где получится :) ).

"Какая разница..Главное - взяли" (с) Соловейчик "Особенности охоты"




Функция ВыделитьПодСтроку(ИсхСтр,Символ)
Перем Стр;

Поз=Найти(ИсхСтр,Символ);

Если Поз>0 Тогда

Стр=Лев(ИсхСтр,Поз-1);
ИсхСтр=Сред(ИсхСтр,Поз+1);
Иначе

Стр=ИсхСтр;
ИсхСтр="";
КонецЕсли;
Возврат Стр;
КонецФункции // ВыделитьПодСтроку

Процедура Загрузить()


Валюта=СоздатьОбъект("Справочник.Валюты");
Стр = "";
МахДата = Дата(0);
Для Н=1 По СписокВалют.РазмерСписка() Цикл

Если СписокВалют.Пометка(Н)=0 Тогда

Продолжить;
КонецЕсли;
ВалютаТМП = СписокВалют.ПолучитьЗначение(Н);
Если (Результат=1)И(Авто=0) Тогда

Сообщить("Загрузка курсов валюты: "+ВалютаТМП+" с сайта ЦБРФ");
Сообщить("Дата"+СимволТабуляции+СимволТабуляции+"Курс"+СимволТабуляции+"Кратность");
КонецЕсли;
Если Авто=1 Тогда

Состояние("Загрузка курсов валюты: "+ВалютаТМП+" с сайта ЦБРФ");
КонецЕсли;

Если (ВалютаТМП.Наименование="EUR") Тогда

КодВалюты="R01239";
КонецЕсли;
Если (ВалютаТМП.Наименование="USD") Тогда

КодВалюты="R01235";
КонецЕсли;
Адрес = "http://www.cbr.ru/scripts/XML_dynamic.asp?VAL_NM_RQ="; //
АдресНачДата ="&date_req1="+Формат(ДатаЧисло(НачДата),"Ч(0)2.0")+"/"+Формат(ДатаМесяц(НачДата),"Ч(0)2.0")+"/"+ДатаГод(КонДата);
АдресКонДата ="&date_req2="+Формат(ДатаЧисло(КонДата),"Ч(0)2.0")+"/"+Формат(ДатаМесяц(КонДата),"Ч(0)2.0")+"/"+ДатаГод(КонДата);
Адрес = Адрес + КодВалюты + АдресНачДата + АдресКонДата ;
Попытка

Соединение.ПолучитьКакСтроку(Адрес,Стр);
Исключение

Сообщить("Неудачная попытка соединения.");
КонецПопытки;
Текст=СоздатьОбъект("Текст");
Текст.ДобавитьСтроку(Стр);


Курсы=СоздатьОбъект("Периодический");
Курсы.ИспользоватьОбъект("Курс",ВалютаТМП);
Кратности=СоздатьОбъект("Периодический");
Кратности.ИспользоватьОбъект("Кратность",ВалютаТМП);

НачальныйКурс=0;
НачальнаяКратность=0;
НачальнаяДатаКурса=Дата(0);
НачатьТранзакцию();

// <ValCurs ID="R01235" DateRange1="02/03/2015" DateRange2="04/03/2015" name="Foreign Currency Market Dynamic">

Для Инд=3 По Текст.КоличествоСтрок() Цикл //первые две строки пропускаем, заголовок.


Стр=Текст.ПолучитьСтроку(Инд);

//Получаем дату курса
ДатаКурсаСтр=ВыделитьПодстроку(Стр,Симв(34));
ДатаКурсаСтр=ВыделитьПодстроку(Стр,Симв(34));

Если НачДата=КонДата Тогда

ДатаКурса=КонДата;
Иначе

ДатаКурса=Дата(ДатаКурсаСтр);
КонецЕсли;
//Кратность
КратностьСтр=ВыделитьПодстроку(Стр,">");
КратностьСтр=ВыделитьПодстроку(Стр,">");
КратностьСтр=ВыделитьПодстроку(Стр,"<");
Кратность=Число(КратностьСтр);
//Собственно курс
КурсСтр=ВыделитьПодстроку(Стр,">");
КурсСтр=ВыделитьПодстроку(Стр,">");
КурсСтр=ВыделитьПодстроку(Стр,"<");
КурсСтр=СтрЗаменить(КурсСтр,",", "."); // заменяем запятые на точку (дробь)
Курс=Число(КурсСтр);

Если ДатаКурса>КонДата Тогда

Прервать;
КонецЕсли;

Если ДатаКурса<НачДата Тогда //Запоминание курса на начало интервала

Продолжить;
КонецЕсли;

Курсы.ВыбратьЗначения(ДатаКурса,ДатаКурса);
Курсы.ПолучитьЗначение();
Кратности.ВыбратьЗначения(ДатаКурса,ДатаКурса);
Кратности.ПолучитьЗначение();
Если (Курс<>Курсы.Значение) или (Кратность<>ВалютаТМП.Кратность.Получить(ДатаКурса)) Тогда

Курсы.ДатаЗнач=ДатаКурса;
Курсы.Значение=Курс;
Курсы.Записать();
Кратности.ДатаЗнач=ДатаКурса;
Кратности.Значение=Кратность;
Если ВалютаТМП.Кратность.Получить(ДатаКурса)<>Кратность Тогда

Кратности.Записать();
КонецЕсли;
Если (Результат=1)И(Авто=0) Тогда

Сообщить(Строка(ДатаКурса)+СимволТабуляции+Курс +СимволТабуляции+СимволТабуляции+ Кратность,"I");
КонецЕсли;
МахДата = макс(ДатаКурса,МахДата);
КонецЕсли;
Если (Результат=1)И(Авто=0) Тогда

Состояние("Загрузка курса на "+ДатаКурса+" - "+Курс);
КонецЕсли;
КонецЦикла;
ЗафиксироватьТранзакцию();
КонецЦикла;
ОбновитьСписокВалют();
Если Авто=0 Тогда
Предупреждение("Загрузка курсов закончена!",3);
Иначе
Состояние("Загрузка курсов закончена!");
КонецЕсли;
СохранитьЗначение("ДатаСкачиванияКурсовВалют",МахДата);
КонецПроцедуры // Загрузить

ireg
05.03.2015, 16:27
)) ничего не имею против 1С, но выглядит забавно, особенно обработка исключений))



Попытка

Соединение.ПолучитьКакСтроку(Адрес,Стр);
Исключение

Сообщить("Неудачная попытка соединения.");
КонецПопытки;


Попытка - Конец попытки)) Надо будет запомнить и при случае употребить)

Ahton
05.03.2015, 16:56
Синтаксис на питона похож, просто пипец :)
Мне в питоне нравится как исключения построены - очень приятно писать код :)

Гарольд
05.03.2015, 17:01
Синтаксис на питона похож, просто пипец :)

Вообщето это не синтаксис, а структурирование модуля для более удобочитаемости.
Можно и в одну строку нашлёпать, как письмо без абзацев.
Но будет очень нечитаемо.




) ничего не имею против 1С, но выглядит забавно, особенно обработка исключений))

Попытка - Конец попытки)) Надо будет запомнить и при случае употребить)

Это делается чтоб код не завис на ожидании события (например в данном случае - соединение с сайтом)

ireg
05.03.2015, 17:09
Это делается чтоб код не завис на ожидании события

Гарольд, я не о задаче, не об алгоритме и способе обработки ошибок) я именно про синтаксис самого языка.

Ahton
05.03.2015, 17:12
я именно про синтаксис самого языка.

Вообщето это не синтаксис, а структурирование модуля для более удобочитаемости.
:acute:Ай-я-яй ))))

ireg
05.03.2015, 17:45
Кстати, а что будет после обработки исключения?
Ну вот случилось у нас исключение, не ответил сайт, интернет отвалился. Вывелось сообщение "Неудачная попытка соединения." А что дальше?
Кстати, объект "Соединение" - какой-то глобальный? не инициализируется и не чистится.

Гарольд
05.03.2015, 18:24
В принципе состояние обрабатываемого объекта не изменится, строка "Стр" останется пустой (как до обработки). Соединение это предопределенная процедура, выполняющая запрос по заданному адресу и возвращающая ответ.

Про синтаксис - я не пойму, как он может быть похож на питона...

ААА тьфу мля.. Я про животное подумал!!!!!!!!!!!!!!!!!!!! :)

Гарольд
05.03.2015, 19:39
Добавлю - курс - значение периодическое (привязано к дате) поэтому в программе будет использоваться предыдущее значение считанного курса.
Придется вводить в справочник валют вручную.

ireg
05.03.2015, 19:43
А по коду не получится так, что в случае исключения обновится значение ДатаСкачиванияКурсовВалют хотя реально код после исключения в общем-то не нужен.
Т.е я имею ввиду значения курсов не обновятся, а дата поставится. Это нормально?

Гарольд
05.03.2015, 20:27
ireg, я привел кусок кода из модуля, который изменил, который именно берет значение валюты с сайта.
Там еще есть процедуры дальнейшей обработки, я не заморачивался их рассмотрением, но если валюта не скачалась - то запоминается последняя удачная дата. Я в них ничего не менял - потому и не выкладывал.

Например в субботу-воскресенье валюты на сайте отсутствуют.. Поэтому берется значение за пятницу.
Пример - запрос с 1 марта по 6-е
А ответ - только с 3-го.
Запрос

http://www.cbr.ru/scripts/XML_dynamic.asp?date_req1=01/03/2015&date_req2=06/03/2015&VAL_NM_RQ=R01235

Ответ

<ValCurs ID="R01235" DateRange1="01/03/2015" DateRange2="06/03/2015" name="Foreign Currency Market Dynamic">
<Record Date="03.03.2015" Id="R01235"><Nominal>1</Nominal><Value>62,2248</Value></Record>
<Record Date="04.03.2015" Id="R01235"><Nominal>1</Nominal><Value>62,3649</Value></Record>
<Record Date="05.03.2015" Id="R01235"><Nominal>1</Nominal><Value>61,8745</Value></Record>
<Record Date="06.03.2015" Id="R01235"><Nominal>1</Nominal><Value>61,8457</Value></Record></ValCurs>

И еще - я не программист 1-с (я электронщик), просто приходится этим заниматься :)

ireg
05.03.2015, 20:59
Я вообще в 1С не вкуриваю) так что не вопрос. Мне просто стало любопытно.
Ты привел пример, в ним все понятно. Я говорил только о случае, когда сработает исключение. Т.е по-хорошему, чтобы протестить указанный мною случай, нужно обрезать провода и запустить код)))

Гарольд
05.03.2015, 21:17
Короче.. Исключение - это эквивалент errorlevel, т.е. что делать если произошла ошибка. Иначе программа вывалится аварийно (ну например)

Попытка
А=1/0;
Исключение
Сообщить("Делить на ноль нельзя!");
КонецПопытки;


Ну как то так. Остальной код модуля - рабочий, типовой. Т.е. ничего страшного не происходит, провода можно не резать!
Если всё же решишься...Не забывай, что первым всегда режется зеленый!

ireg
05.03.2015, 21:59
Гарольд) я прекрасно знаю, что такое исключения) и как это работает. Помимо программирования на разных языках, у меня еще большой опыт в реверсе кода, поэтому отлично знаю как исключения транслируются в разных языках.
Обычно в блоке исключения ставят критический код, у которого может произойти как аппаратное исключение (как деление на 0), так и программные исключения, генерируемые умышленно. За свою практику я переписал тонны кода с одних языков на другие, приходилось видеть и по 4 вложенных try. Многие, кто активно применяет исключения, пишут не очень корректный код в случае срабатывания исключений. Ну там например создали объект, в блоке try - пытаются что-то сделать, получают исключение и на выход... А кто будет убивать созданный объект - одному Богу известно. Прога конечно работает, память жрет, некорректно освобождает, а кому до этого дело?))

А в твоем случае, я думаю, в случае срабатывания исключения в базу (ДатаСкачиванияКурсовВалют) запишется текущая дата, хотя на самом деле предположим уже неделю нет интернета. Т.е значение ДатаСкачиванияКурсовВалют будет записано в любом случае, даже если фактически данные мы не получили. По хорошему, нужно либо весь код обработки внести в блок, либо завести какой-то флаг. Но лучше всего получить данные, убедиться, что мы их получили и они корректны, и только потом работать с БД. Т.е только после подтверждения успешного получения данных.
1) получаем данные
2) в случае исключения выводим сообщение, устанавливаем результат (если предполагается даже в случае ошибки), убиваем занятые до блока (и в самом блоке) ресурсы и выходим из функции
3) проверяем данные на корректность - шаг не обязательный
4) а теперь уже можно и парсить, и транзакции с БД выполнять.

-ЗАНОЗА-
05.03.2015, 22:29
не в тему, но вы такие умные...подскажите, с флешки стерты фотографии, их реально восстановить? (если что перекиньте в нужную тему)

ireg
05.03.2015, 22:40
но вы такие умные...подскажите

мы еще и крестиком вышиваем... мррр... и на машинке....

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

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

-ЗАНОЗА-
05.03.2015, 23:14
спасибо...но записали сверху...

Гарольд
05.03.2015, 23:23
А в твоем случае, я думаю, в случае срабатывания исключения в базу


У меня небыло задачи переписывать полностью модуль.
Я только заменил обращение к РБК на обращение к ЦБРФ и расшифровку полученных данных, всё остальное - типовое 1-с - as is - потому не заморачивался.
Я ж в начале сказал зачем это понадобилось - с РБК стандартной процедурой зачастую получаешь курс за понедельник уже к пятнице :).

Насчёт флэшки тут уже была тема как спасать. Правильно сказали - первым делом ничего не записывать.
Была тема тут например http://dalas.ru/showthread.php?t=13074

Гарольд
07.03.2015, 15:20
Московская биржа в 12.40 мск возобновит остановленные из-за сбоя торги
"Причиной нештатной ситуации на валютном рынке 5 марта 2015 года явилась некорректная обработка серверами доступа торговой системы валютного рынка транзакции сервиса балансировки риска между срочным и валютным рынками биржи", — поясняется в другом сообщении биржи.

Нифига себе я курс валюты на другой сайт настроил :) ... все транзакции поломал :)

Гарольд
24.06.2015, 20:16
Начал обновлять Зарплату (ЗИК) - конфигуратор выдал "различие в модулях"...

Модуль-обработка "Расчет страховых взносов"

Текущая формула вычисления:

База = База - ВсегоНачислено - НеОблагается - Скидки;

В новом релизе.
База = База - (ВсегоНачислено - НеОблагается - Скидки);

Это что, с точки зрения программеров 1-с - одинаковые выражения, скобочек не жалко?

Мать Тереза
24.06.2015, 21:28
С математической точки зрения это разные выражения.
с 1-с-овской тоже

Гарольд
24.06.2015, 21:39
Мать Тереза, да вот и думаю, как можно программировать не зная азов математики..?? минус перед скобочкой - при раскрытии знаки в скобках меняем.
И наоборот. Думаю что забыли в скобочках заменить.

И немного юмора, заметил несколько проверок даты на 2018 год...
Шо, таки в 2017, ровно через 100 лет, что то глобальное ожидается?

Мать Тереза
24.06.2015, 22:23
наоборот. Думаю что забыли в скобочках заменить.

По сути база должна быть как раз равна (ВсегоНачислено - НеОблагается - Скидки). Хорошо бы в отладчике посмотреть, что в Базе сидит перед этим выражением.



И немного юмора, заметил несколько проверок даты на 2018 год...
Шо, таки в 2017, ровно через 100 лет, что то глобальное ожидается?

Перестраховываются :smile:
А вообще-то, кажется именно с 2018 года меняется принцип учета "вредников" - не первый и второй список, а другая классификация.