v8: Типичные ошибки на 1С 80 Ключевые слова: программирование,чайник
Коллекции объектов, а не ссылок
Не стоит увлекаться коллекциями, содержащими объекты. Помните, что объект - это участок памяти, содержащий все реквизиты объекта. Поэтому он занимает многократно больше места, чем ссылка на него.
Я часто увлекался в логах хранением не ссылок, а объектов, в результате чего после некоторого числа итераций система сначала тормозила, а потом висла из-за переполнения памяти.
Слишком длинные таблицы в форме
Не стоит увлекаться слишком большими таблицами в форме. Если вы действительно хотите вывести очень большую таблицу, лучше выводите ее порциями, или с помощью фильтра. 1С падает на очень больших таблицах, отображаемых в форме.
Одинаковые имена
Это достаточно разнообразная тема. Суть ее в том, что вы ожидаете, что работаете с одной переменной, а на самом деле работаете с другой.
Разные языки
Сумма=2;
Сумма=""+Cумма+"1";
Сообщить(Сумма);
Как вы думаете, какой результат получится? 21? Не угадали, "1". Дело в том, что во второй строчке вторая буква С - латинская.
Часто такая ошибка сводит с ума.
Глобальные и локальные переменные
Пусть у нас объявлена глобальная переменная Счетчик.
Если мы в процедуре будем использовать Счетчик, то мы обращаемся не к локальной переменной Счетчик, а к глобальной переменной. Поэтому все локальные переменные желательно объявлять в процедуре, дабы избежать возможной путаницы. Также желательно глобальным переменным давать имена, которые явно указывают на их глобальность, например глСчетчик.
Реквизиты формы
Иногда вы пишите Контрагент=Неопределено и думаете, что присваиваете значение локальной переменной Контрагент, но если этот код записан в модуле или форме документа, у которого есть реквизит Контрагент, то на самом деле присвоение идет этому реквизиту.
Способ борьбы с этой багой такой же - обязательное объявление всех используемых локальных переменных. Тогда присвоение все же будет идти в локальную переменную.
Номер и дата документа Момент получения номера документа
Номер документа нужно устанавливать после установки даты документа, т.к. иначе 1С не может проверить уникальность номера и может ругаться по этому поводу.
Установка нового номера
Если есть ВН01 и ВН-02, то установить новый номер "ВН" выдаст ВН-03, а не ВН02. Это криво и лучше использовать свой нумератор.
Смена отбора
Нарваться на ошибку можно и когда вы меняете вид отбора.
Например: пусть в отборе стоит вариант отбора в списке, отбор активен, значение отбора - некий список.
Потом я хочу поменять отбор на другой вид отбора - например на отбор по значению, пусть так как это сделано в коде:
Форма.СправочникСписок.Отбор.ВидСклада.Значение= Перечисления.ВидыСкладов.НеавтоматизированнаяТорговаяТочка;
Форма.СправочникСписок.Отбор.ВидСклада.Использование=Истина;
Форма.СправочникСписок.Отбор.ВидСклада.ВидСравнения=ВидСравнения.НеРавно;
Отсюда мораль - прежде чем менять отбор, нужное го отключать, т.е. правильный код такой:
Форма.СправочникСписок.Отбор.ВидСклада.Использование=Ложь;
Форма.СправочникСписок.Отбор.ВидСклада.Значение= Перечисления.ВидыСкладов.НеавтоматизированнаяТорговаяТочка;
Форма.СправочникСписок.Отбор.ВидСклада.Использование=Истина;
Форма.СправочникСписок.Отбор.ВидСклада.ВидСравнения=ВидСравнения.НеРавно;
Преобразование чисел к строке
В 1С по умолчанию числа преобразовываются к строке не так как в 77, т.е. не так как во всех нормальных языках программирования, а используя региональные стандарты. Число 1000 может преобразуется не в "1000", а в "1 000". Поэтому не пишите С=Строка(Ч), а пишите С=Формат(Ч, "ЧГ="), а лучше заведите для этих целей отдельную функцию.
Я погорел, когда обрабатывал таблицы в несколько тысяч строк и использовал адрес вида "R10C100". После первой тысячи строк программа вылетала, потому что адрес становился "R1 000C100".
Регистры сведений Отборы в запросах по регистрам сведений
Не нужно увлекаться параметрами таблиц. Если вам нужно получить например все договора со статусом "Закрыт", не нужно писать:
ВЫБРАТЬ Договор ИЗ СтатусыДоговоровСрезПоследних(,Статус=&Открыт)
Пишите:
ВЫБРАТЬ Договор ИЗ СтатусыДоговоровСрезПоследних(,) ГДЕ Статус=&Открыт
Я на этом погорел. Первый вариант отбирает все движения по закрытию договора, т.е. выдаст все договоры, которые когда-либо были открыты. Второй запрос выдаст открытые на текущий момент договоры.
Обращение к документу-регистратору записи РС
Можно конечно обратиться к документу-регистратору, который сделал запись. Например если статус договора "Закрыт", можно посмотреть, каким документом была сделана эта запись "Закрытие договора" или "Отмена договора", но если например произойдет завершение периода, то у договора будет просто статус "Закрыт" и непонятно будет, закрыт он из-за завершения по нему работ или из-за отмены.
Это ошибка проектирования, если приходится обращаться к документу, сделавшему запись по регистру сведений.
|