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

  • Автор темы Автор темы vitfil
  • Дата начала Дата начала
V

vitfil

Собственно, описываются проблемы, которые приходилось решать, а также причины их возникновения. Ну, и некоторые полезные советы.

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

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

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

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

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

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

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

1) Установка флага БыстраяОбработкаДвижений. Очень полезен при частых расчетах регистра задним числом, а также при снятии отчета за не полный период.
При установке этого флага в таблицу движений регистра добавляется поле Date_Time_IDDoc и IDDocDef, что убирает необходимость присоединения таблицы _1SJourn для определения даты.

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

Пример: Регистр.Партии: Склад, Товар, Партия, Фирма

Отбор по партии практически не нужен, поэтому правильно расположить измерения так: Товар, Склад, Фирма, Партия

3) Установка флага отбор движений у измерения


1 и 3 способы приводят к заметному увеличению индекса, поэтому нужно помнить о балансе записи и чтения.
 
Понедельник. И решил он начать работать с 1С. И обратился на форум с вопросом:
У меня огромная проблема(на мой взгляд). Ни разу не сталкивался с 1С, но вот пришлось. Во-первых кто бы мог поделиться ссылкой на 1С бухгалтерия 7.7 или 8.0. Понимаю конечно, что продукт распространяется в основном по лицензии но все таки. Также нужна какая нибудь база для нее(какая нибудь тестовая). Также хотел спросить как конфигурировать программу(в плане того чтобы например в какой нибудь накладной поменять название полей таблицы, добавить некоторые поля). С каких книг следует начать, чтобы хоть чуть чуть въехать в курс дела? Заранее спасибо

И ответил ему злой админ:
Я бы порекомендовал для начала просмотреть учебник на , а также почитать. Ну и, в обязательном порядке ЖКК - "Администрирование и конфигурирование" и "Описание встроенного языка". Это все касается 7.7.
И не было это рекламой, потому как знания в рекламе не нуждаются.

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

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

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

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab