Жил-был программист...

Тема в разделе "1C и всё что с ней связано", создана пользователем vitfil, 25 июл 2008.

  1. vitfil

    vitfil IT-интегратор

    Регистрация:
    2 апр 2004
    Сообщения:
    2.070
    Симпатии:
    0
    Собственно, описываются проблемы, которые приходилось решать, а также причины их возникновения. Ну, и некоторые полезные советы.

    Транзакции, будь они неладны
    Имеем следующий код:

    Процедура ОбработкаПроведения()
    ...
    Спр = СоздатьОбъект("Справочник.ХХХ");
    Спр.НайтиЭлемент(...);
    Попытка
    Спр.Записать();
    Исключение
    КонецПопытки;
    ...
    КонецПроцедуры

    И где-то в глобальнике...

    ...
    Спр = СоздатьОбъект("Справочник.ХХХ");
    Спр.НайтиЭлемент(...);

    В результате получаем ошибку попытки прочитать данные, находящиеся в транзакции, созданной другим пользователем. А заодно и увещевания, что 1С настолько тормознутая, что не может прочитать элемент из справочника, в котором всего-то 20 позиций.

    Объяснение.
    Вся процедура ОбработкаПроведения неявно заключена в транзакцию. Следовательно, все данные, которые изменяются в этой транзакции, типа Спр.Записать() не пишутся напрямую в базу, а включаются в пакет транзакции для возможности отката при СтатусВозврата(0). Следовательно, таблица используемого справочника будет заблокирована. А так как 1С не выполняет "грязных" чтений данных, получаем описанную выше ошибку.

    Оптимизация регистров
    Собственно, взято из доки по 1с++, но будет полезным знать даже если не используете оную компоненту.
     
  2. vitfil

    vitfil IT-интегратор

    Регистрация:
    2 апр 2004
    Сообщения:
    2.070
    Симпатии:
    0
    Понедельник. И решил он начать работать с 1С. И обратился на форум с вопросом:
    И ответил ему злой админ:
    И не было это рекламой, потому как знания в рекламе не нуждаются.

    Попытка, как говорится, не пытка...
    Разговор с одним из разработчиков навел меня на мысль, что иногда программисты путают «обработку ошибки» и «предотвращение ошибки». Т.е. вместо того, чтобы «не делать» ошибки (особенно если известна причина ее возникновения) пытаются дождаться исключения и обработать его. Казалось бы, "ловкое" использование конструкции Попытка\Исключение ведет к более стабильной работе программы, но на самом деле конструкция показывает, что программа работает не так, как того хотелось бы. Например, следующий код
    Код (Text):
    Функция ПолучитьКонтрагента(Конт) Экспорт
    Перем Контр;
    Попытка
    Контр = Конт.Контрагент;
    Исключение
    Контр = ПолучитьПустоеЗначение("Справочник.Контрагенты");
    КонецПопытки;
    Возврат Контр;
    КонецФункции
    говорит не о том, что программист пытается избежать ошибки, когда в документе отсутствует реквизит "Контрагент", а о том, что он не знает, как проверить существование этого реквизита. Более того, если реквизит содержится в табличной части документа... Думаю, мысль понятна.

    Ну и самое интересное: Попытка\Исключение работает медленней Если\КонецЕсли. Значительно медленней! Порой замедление может быть в ТЫСЯЧИ раз. Конечно, когда речь идет о миллисекундах... А если пользователей - десятки, подобных конструкций - сотни, вызовов - тысячи, получим еще одно подтверждение о "необычайной тормознутости 1С".

    Несмотря на все свое несовершество, ТиС во многом может служить примером "красивого" программирования.
    Код (Text):
    Функция глЕстьРеквизитШапки(ИмяРеквизита, ВидДокумента) Экспорт     
    Если ПустоеЗначение(ИмяРеквизита) = 1 Тогда
    Возврат 0;
    ИначеЕсли Метаданные.ОбщийРеквизитДокумента(ИмяРеквизита).Выбран() = 1 Тогда
    Возврат 1;
    ИначеЕсли ПустоеЗначение(ВидДокумента) = 1 Тогда
    Возврат 0;
    ИначеЕсли Метаданные.Документ(ВидДокумента).РеквизитШапки(ИмяРеквизита).Выбран() = 1 Тогда
    Возврат 1;
    Иначе
    Возврат 0;
    КонецЕсли;
    КонецФункции
    Функция ПолучитьКонтрагента(Конт) Экспорт
    Перем Контр;
    Если глЕстьРеквизитШапки("Контрагент",Конт.Вид()) = 1 Тогда
    Контр = Конт.Контрагент;
    Иначе
    Контр = ПолучитьПустоеЗначение("Справочник.Контрагенты");
    КонецЕсли;
    Возврат Контр;
    КонецФункции
    Используйте Попытка\Исключение не для предотвращения ошибок, а для обработки исключительных ситуаций, и будет вам счастье в виде просветления.
     
  3. vitfil

    vitfil IT-интегратор

    Регистрация:
    2 апр 2004
    Сообщения:
    2.070
    Симпатии:
    0
    Уловка с сортировкой
    И пришел пользователь, и взмолился он: "Сделай мне сортировку в справочнике Пользователи по реквизиту Подразделение навсегда автоматом".
    И решил он, что легко это сделать. Поставил у реквизита признак "Сортировка". Написал следующий код:
    Код (Text):
    Процедура ПриОткрытии()
    Сортировка("Подразделение",1);
    КонецПроцедуры;
    Проверяем! Оппа: "Неверное имя реквизита".
    Ерунда! Копипастим имя реквизита и... хм. Опять та же ошибка. Неправильно скопипастил? Нет...
    Сортировка работает только для Кода, Наименования и реквизитов простых типов.
    Проверено на сиквельной версии 25-го релиза. Можно ли это обойти? Уверен, что можно, потому как в интерактивном режиме работает для любого типа реквизита. Как обойти? Пока не знаю...
    Самое интересное, что про... кстати, это баг или фича?... в документации ни слова не сказано.
     
Загрузка...

Поделиться этой страницей