1с ошибка при вызове серверного метода

Обновлено: 07.07.2024

С подобной ошибкой я уже сталкивался, она обычно возникала, когда я пытался передать неправильные данные с сервера на клиент (результат запроса, например). Но путем трассировки я выяснил, что на этот раз ошибка возникает вовсе не при возврате из функции, а при передаче параметра с клиента на сервер! Призадумался я - параметр у функции единственный и является он ссылкой на элемент справочника. В соседней обработке такой же точно вызов отлично работает, а в этой не хочет работать совершенно. Любопытства ради сделал функцию, которая принимает один параметр (ноль) и возвращает тоже ноль. Не работает! Та же самая ошибка при вызове функции! Поэкспериментировав немного, я понял, что ошибка возникает при передаче ЛЮБЫХ параметров ЛЮБОГО типа с клиента на сервер О_о. Я никогда не сталкивался с подобным и решил проверить, чем моя нерабочая обработка отличается от рабочей. После недолгих изысканий я обнаружил единственное существенное различие в моих двух обработках - в новой обработке есть макет-таблица, а в старой нет. Чувствуя себя настоящим шаманом, выпилил процедуру загрузки макета на форму, и. внезапно все серверные процедуры и функции снова заработали О_о. Собственно вопрос, в чем дело? Процедуры и функции прилагаются!

Итак, ошибки при передаче параметров появляются после выполнения следующего кода:

__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь


Ошибка передачи данных между клиентом и сервером
Группы и элементы справочника "Номенклатура" имеют реквизит "Услуга". Если в группе меняется.

Ошибка передачи данных в dataGridView
Данный код должен передавать данные с 1 формы на другую в dataGridView. Но срабатывает исключение.

Ошибка передачи данных - сокеты
Проблема состоит в следующем: работаю с сокетами, пытаюсь передать три строки от клиента к серверу.


Ошибка канала передачи данных
Всем привет! студия XE5 postqresql установленная на виртуальной машине, все настроено по факу, до.

Встречали ли такое? Создаёшь себе событие у таблицы формы. Никого не трогаешь.


А тут бац - нельзя создать процедуру на сервере. Неожиданно


Почему? Можно, конечно, почитать в Синтаксис Помощнике. Но зачем? Опять, небось, платформа косячит! Поэтому часто разработчики пытаются её перехитрить:

Выбирают создание "на сервере без контекста"


и удаляют текст "БезКонтекста"


Платформа не ругается, проверки синтаксиса проходят. Profit.

В действительности же, так делать не есть хорошо и может привести к неожиданным последствиям. Вплоть до падения платформы.

Обратимся всё же к Синтаксис Помощнику:


Как видим, сразу пишут о том, что так делать нельзя.

В обработчике данного события нельзя использовать серверные методы формы с директивой компиляции &НаСервере, а также изменять свойства, которые могут привести к серверному вызову.

Что это значит? Что в ПриАктивацииСтроки() нельзя изменять Заголовок, Доступность, Подсказку и т.д. Проверить это легко:


Так а почему? Самый быстрый пример:


Изменение заголовка колонки приводит к обращению к серверу. На этой гифке можно лицезреть результат - бесконечный цикл платформы:

Как это работает? Событие ПриАктивацииСтроки изменяет свойство, которое выполняет обращение к серверу, что снова вызывает событие ПриАктивизацииСтроки. И так до бесконечности (или же до падения платформы).

А вот ещё одно интересное поведение. Допустим, в ПриАктивацииСтроки() код выпал в ошибку:


Если это произойдёт в клиентском методе, то всё хорошо. Пользователь закроет окошко с ошибкой и продолжит работать:

То же произойдёт в методе НаСервереБезКонтекста


Но стоит применить директиву &НаСервере, как будет интересное поведение.


Теперь ошибка будет повторяться бесконечно. И ничего, кроме завершения работы сеанса, не поможет пользователю избавиться от неё.

Вот такая незадача.

Но проблема не только в ПриАктивацииСтроки(). Есть и другие методы, например, ПередНачаломИзменения(). В каждом из таких методов будет описан соответствующий комментарий в Синтаксис Помощнике. Что будет, если нарушить его указания?

Вот такое поведение нам удалось поймать на "продуктиве".

Суть кода: ПередНачаломИзменения() код обращается на сервер, делает запрос и получает строку, которую нужно присвоить в свойство поля формы "ПодсказкаВвода".

Мы же для примера приведем упрощенную реализацию без запроса.

В нашей тестовой обработке ПередНачаломИзменения() у нас срабатывает процедура:



Далее: в обработке имеется ОбязательнаяКолонка. И, если её не заполнить, произойдёт такое:


Ничего не обычного, всё работает. Но! Если вдруг пользователь откроет обработку и, не кликая на таблицу, нажмёт на кнопку проверки, то произойдёт падение с записью дампа:

Такое необычное поведение встретилось у нас на работе в продуктивной базе в форме документа. Представляете, как были недовольны пользователи, которые периодически натыкались на падающую от записи документа платформу?)

1. Не обращаемся к серверу

Часто разработчики делают то, что им не нужно (или так, как нет нужды). Далеко не всегда нужно обращаться на сервер. И далеко не всегда нужно производить действия, которые к этому приведут. Можно пересмотреть код в таких событиях. Например, в нашей ситуации с бесконечным изменением заголовка группы формы, можно воспользоваться свойством "ПутьКДаннымЗаголовка".

Для этого добавляем строковый реквизит:


А в свойствах группы указываем его:


А в коде меняем не заголовок группы, а значение строкового реквизита:


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

2. Используем &НаСервереБезКонтекста

Чаще всего обращения к серверу в подобных событиях можно сделать &НаСервереБезКонтекста. Просто далеко не всегда разработчик задумывается об этом заранее. Нужны данные формы в методе? Можно их передать. Чаще всего этого достаточно, главное - не лениться.

3. Запоминаем обработанную строку

Если уж нет никаких вариантов и нам нужно обязательно выполнить именно серверный метод, то можно попробовать просто запомнить последнюю обработанную строку и игнорировать попытки сделать это повторно. Вот пример реализации:

Добавляет числовой реквизит формы (или общую переменную формы "ТекущаяСтрока"). И дорабатываем наш метод:


4. Обработчик ожидания

Можно использовать обработчик ожидания. Например, в ПриАктивацииСтроки() не выполнять серверный код напрямую, а выполнять одноразовое выполнение обработчика ожидания, в котором уже происходят нужные действия.


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

Выводы

При разработке, старайтесь внимательно читать СП\ИТС и следовать рекомендациям. Можно, конечно, следовать принципу "главное работает". А в какой-то момент столкнуться с неожиданным поведением платформы. Потому что, в описанных нами примерах, ошибки могут вылезти в самый неожиданный момент. И уже на продуктиве =)

P.S.: А вообще, раз уж описан такой запрет в СП, то почему бы не сделать его на уровне проверки синтаксиса платформы? ¯\_(-_-)_/¯

Понравилась статья?

Не будьте равнодушными! Поставьте лайк плюс и переходите к другим статьям:

Специальные предложения

Electronic Software Distribution

Интеграция 1С с системой Меркурий

Алкогольная декларация

Готовые переносы данных

54-ФЗ

Управление проектом на Инфостарте

Траектория обучения 1С-разработчика

"Меньше копипаста!", или как Вася универсальную процедуру писал
хочу спросить про старую публикацию: Вася в конце концов дописал свою универсальную процедуру или нет? (1) Да, там в самом конце есть спойлер с "Окончательная Васина процедура"

Отличная статья на малоизвестную тему ситуации, с которой легко столкнуться,но очень трудно понять в чём дело и открыть правильный раздел в синтаксис помощнике! Я, вот, сталкивался с такой проблемой, но как-то не задумывался в её причинах и не удосужился об этом прочитать в синтаксис помощнике.
ТЕПЕРЬ БУДУ ЗНАТЬ!
Статья МАСТ РИД всем!
Решал ранее переменной флагом мТакоеТоСобытиеВызвано - когда обработчик вызывался первый раз - флаг выставлял и выполнял серверный вызов - когда второй раз - сбрасывал флаг и выходил из обработчика.
Кстати в статье тут единственное место - к чему я бы придрался - плохо описано в п.3 применение переменной "ТекущаяСтрока" - надо было указать что это глобальная переменная моудля формы (или реквизит формы) и если это переменная то правильно было назвать её с префиксом м "мТекущаяСтрока" - но это мелочи.

Вот бы ещё проблему ошибки "Неизвестный идентификатор формы" побороть, когда после некоторых серверных вызовов при очередном серверном вызове возникает такая ошибка (встречал частенько в разных управляемых формах)
Вот этот, последний, случай возникает при применении общей типовой формы отчета в ЗУП 3.1 во внешнем отчёта (сначала формирую отчет с одним вариантом, а затем переключаю на другой - и ошибка):

Неизвестный идентификатор формы
: ЗагрузитьВариант(ВариантФормы.КлючВарианта);

по причине:
Неизвестный идентификатор формы

Повторное формирование отчета уже закрывает форму с ошибкой

Расширения конфигурации:
- Прямые выплаты сотрудникам старше 65 лет (1.0.2.25)
- Оформление пропусков на время карантина COVID-19 (1.0.0.12)

Режим: Серверный (сжатие: усиленное)
Приложение: Тонкий клиент
Локализация: Информационная база: русский (Россия), Сеанс: русский
Вариант интерфейса: Такси

Ошибки:
--------------------------------------------------------------------------------
12.05.2020 9:35:00
Ошибка создания источника доступных настроек компоновки данных
e3d0252c-bb72-46f3-b1c3-11f5f681cd00
--------------------------------------------------------------------------------
12.05.2020 9:33:33
Неизвестный идентификатор формы
: Результат = РезультатФормированияОтчета(ФормированиеПриОткрытии, НастройкиОтчета.Внешний Или НастройкиОтчета.Безопасный);
: Сформировать();

Причём когда сделал свою форму с таким вот обработчиков формирования (из общей формы)

Проблема сохоранилась (и кстати, обработчики объекта отчета "ПриКомрпоновкеРезультат" вообще не запускался.

Решил только переходом на классическое формирование отчета через встроенную команду формы "Сформировать" (ну или через программный вызов метода формирования у формы).

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

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

В этой статье мы покажем, как взаимодействуют клиентская и серверная части платформы и какие есть особенности в использовании директив компиляции.


Однако при разработке на 8.0 и 8.1 о разделении кода на клиентскую и серверную часть можно было не заботиться, поскольку на клиенте (на толстом клиенте) был доступен тот же функционал, что и на сервере.

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

Немного базовой теории

Перед тем, как перейти к содержательной части, договоримся о некоторых ограничениях:

Далее, освежим в памяти немного теории.

Директивы, в имени которых упоминается «Клиент», устанавливают ограничение на обращение к базе данных.

Процедуры или функции, написанные под директивой «Без контекста», не имеют доступа к контексту (данным) формы. Исходя из этой информации, легко представить ограничения директив по доступу к данным в виде следующей таблицы:

Опережая вопрос «Для чего же директива с самым длинным названием, если она ограничивает и использование контекста форм, и обращения к базе данных?», напомню: любая процедура и функция поддерживает обработку информации, переданной в неё в качестве параметров.

Не стоит забывать и про доступность вызова одних процедур и функций из других. Для этого стоит запомнить, что можно вызывать только те процедуры и функции, которые находятся под одноимённой (с родительским методом) директивой или под директивой, находящейся ниже (чем у родительского метода) согласно списку:

Теперь про серверный вызов

Самый первый серверный вызов инициализируется в момент начала сеанса работы 1С. То есть когда пользователь выполняет вход в информационную базу:

Всё очень просто:

Обратите внимание, что доступ к базе данных есть только на серверной части, а соединение между клиентом и сервером имеет ограниченную пропускную способность. Это и неудивительно – ведь соединение между клиентской и серверной частью может быть установлено даже по нестабильному низкоскоростному каналу связи (например, посредством мобильного интернета).

Кроме этого, передача данных между клиентом и сервером возможна только посредством серверного вызова.

Видим, что на стороне клиента у нас будут доступны процедуры и функции, написанные под двумя директивами из четырёх, а на стороне сервера – под тремя из четырёх.

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

И в этом нам помогут наши новые друзья, знакомьтесь!

Это процесс клиентской части приложения «1С:Предприятие 8». Он запускается на компьютере пользователя и сожительствует в оперативной памяти с другими процессами (38 вкладок браузера, поток аудио из социальной сети, telegram и другие). Может порождать серверный вызов.
Это процесс серверной части приложения «1С:Предприятие 8». Он существует на сервере 1С. Знает, какие клиентские сеансы в данный момент запущены, но самостоятельно не может инициировать взаимодействие с ними. Работает с клиентской частью только через полученный от неё серверный вызов. А это серверный вызов. Как было сказано выше, он порождается процессом клиентской части и призван «прислуживать» ему. Он передает запросы со стороны клиента на сторону сервера, а также занимается транспортировкой данных с клиента на сервер и обратно.

Итак, давайте рассмотрим несколько особенностей работы программного кода в «1С:Предприятие 8», написанного под разными директивами.

Действие 1. Открытие пользователем формы с данными.

В момент нажатия Пользователем кнопки открытия формы из интерфейса, происходит передача управления на Сервер. По переданным параметрам получаются необходимые для построения данные из БД и происходит формирование контекста формы, который затем отправляется на клиентскую часть. У пользователя на экране отображается запрошенная форма.

Действие 2. Получение из открытой Пользователем формы дополнительных данных из Базы данных.

После выполнения метода на сервере, весь этот «пакет» транспортируется обратно. Таким образом, форма со всеми элементами и данными дважды проходит через самое узкое место системы.

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

Кстати, именно поэтому до версии платформы 8.3.7.1759 на сложных формах для управления видимостью элементов рекомендовалось использовать панели со страницами, а не свойство «Видимость». Только начиная с этого релиза отработка изменения видимости элементов стала выполняться на стороне клиента.

Действие 3. Обработка данных табличной части формы с получением дополнительной информации из Базы данных.

Явление 1. Построчная обработка табличной части на стороне клиента с организацией серверного вызова для получения дополнительной информации из базы данных.

При таком построении программного кода происходит множественное обращение со стороны клиента на сервер – по количеству элементов цикла, запущенного на стороне клиента.

Явление 2. Предварительная обработка табличной части на стороне клиента с целью подготовки требуемых к обработке на сервере данных и «упаковки» их в набор параметров. Затем передача этого набора на сервер для получения дополнительной информации из базы данных.

В данном случае количество серверных вызовов сведено к минимуму за счёт предварительной подготовки параметров.

Большое количество текущих серверных вызовов может свидетельствовать о неоптимальном программном коде.

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

Действие 4. Выполнение обработки данных.

Когда предполагается выполнение одной и той же обработки данных из нескольких участков программного кода, разумно этот код поместить в самостоятельную процедуру или функцию. Остаётся только решить, под какой директивой её написать.

Та-дам!

Для копирования у нас есть ксерокс. Но куда его поставить? На сторону клиента или сервера? Под какой директивой его разместить?

Как было озвучено ранее – любая процедура и функция поддерживает обработку информации, переданной в неё в качестве параметров.

Но что произойдёт, если потребность в копировании возникнет на стороне сервера? Например, для подготовки данных, передаваемых на сторону клиента, потребуется сделать копию? Напомню – процесс серверной части не имеет возможности самостоятельно инициировать клиентские вызовы.

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

Не углубляясь в детали, отметим, что метод, описанный под данной директивой управления, создаётся в двух копиях – и на стороне клиента, и на стороне сервера. Это позволяет выполнить необходимые действия там, где появилась потребность в них (клиент/сервер), без лишних серверных вызовов.

С точки зрения выполнения программы результат будет одинаков. Но объяснение «почему так не надо делать» – это уже совершенно другая тема…

Вместо заключения

В данной статье мы на наглядных примерах рассмотрели влияние различных директив компиляции на такое явление системы «1С:Предприятие 8», как серверный вызов. Как видно, основная причина для выбора правильной директивы – производительность транспортировки данных между клиентской и серверной частью.

Придерживайтесь при разработке следующих правил:

  • По возможности не передавайте контекст формы на сторону сервера
  • Минимизируйте количество текущих серверных вызовов
  • Длительные и ресурсоёмкие задачи запускайте на выполнение на стороне сервера (при возможности – в фоновом режиме).

Учитывайте потребность в доступности тех или иных видов данных, обоснованность передачи управления и не стесняйтесь при необходимости дробить процедуры и функции. И будет Вашему серверному вызову всегда легко, а Вы от пользователей Вашей программы получите «молчаливую благодарность»!

Так ли это важно думать об оптимизации? Тут имеет смысл вспомнить одну историю.

Программист Иван при доработке 1С на своём предприятии сделал ошибку в выборе директивы компиляции. Из-за неё длительность одного из серверных вызовов была больше возможной на полсекунды.

Пользователей, применяющих этот функционал, – 25 человек, и каждый из них за рабочий день в среднем совершает 110 таких операций. Всего впустую за рабочий месяц потрачено 28875 секунд (21 рабочий день * 25 человек * 110 операций * 0,5 секунды) = 8,02 часов.

Иван, каково тебе осознавать, что за месяц ты задолжал своему предприятию целый рабочий день?

1С ошибка Поле объекта не обнаружено

Мы же будем оперировать фактами. В конце статьи прилагается внешняя обработка, в которой воспроизведена данная ошибка.

  • Удалили табличную часть, к которой обращаемся в коде?
  • Переименовали реквизит, а в коде не исправили?
  • Заменили значение со ссылки на неопределено?

Индекс находится за границами массива

1С ошибка Индекс находится за пределами массива

Обращение к процедуре как к функции

ОШибка

Суть этой ошибки в том, что процедура не может возвращать значение. И если мы в коде используем вызов процедуры справа от знака присваивания, это приведет к ошибке.

А вот неправильное использование процедуры синтаксическая проверка (Ctrl + F7) успешно обнаруживает, и не даст сохранить конфигурацию или внешнюю обработку/отчет, пока ошибка не будет устранена.

Рассмотрим два примера:


Процедура не может возвращать значение

Переменная не определена

Такой текст ошибки платформа 1С выдает на этапе синтаксического контроля, при сохранении конфигурации, внешнего отчета или обработки.
Причин у этой ошибки может быть несколько.

Значение не является значением объектного типа


Разберем более сложный пример:

Ошибка при вызове метода контекста

Ошибка при вызове метода контекста

Обнаружены ошибки в 1С Синтаксическая ошибка

Чаще всего ошибка при вызове метода контекста встречается в следующих методах:

  1. Записать
  2. Прочитать
  3. Выполнить
  4. Создать
  5. ПроверитьВывод
Разберем эту ошибку на примере метода Выполнить объекта Запрос:

Тип не может быть выбран в запросе в 1С 8.3 (8.2)

Ошибка Тип не может быть выбран в запросе

С такой ошибкой начинающие разработчики (да и не только начинающие 😉 ) сталкиваются чаще всего, при чтении запросом данных из таблиц значений, либо из регистров сведений. Все дело в том, что запросы поддерживают далеко не все типы значений. Так, например, нельзя запросом выбрать тип Картинка, ХранилищеЗначений, Шрифт, и многие другие типы, которые не относятся к примитивным или ссылочным типам значений.

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

Использование в 1С модальных окон в данном режиме запрещено

Ошибка Использование в 1С модальных окон в данном режиме запрещено​

1С 8.3 и 8.2: Запись с такими ключевыми полями существует!

Данная ошибка появляется при некорректной записи в регистр сведений. Чаще всего с этой ошибкой сталкиваются начинающие разработчики, не до конца понимающие механизмы работы с ключевыми полями (измерениями).

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

Поле объекта недоступно для записи в 1С

Ошибка Поле объекта недоступно для записи в 1С​

Ссылка на обработку

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

Читайте также: