1с в параметре неопределено
Здравствуйте, коллеги! Сегодня поговорим о проблеме неопределенных переменных в 1С. Рядовой пользователь с данной ошибкой сталкиваться не должен, но если уж и произошло подобное при работе в типовой конфигурации 1С, которая никак не модифицировалась, возможно, у нас наклевывается проблема самого релиза, которая иссякнет при обновлении. В таком случае стоит связаться со специалистом, чтобы найти выход из ситуации.
Если же Вы сами занимаетесь разработкой и столкнулись с ошибкой, «Переменная не определена в 1С», то следует обратится к конфигуратору, найти, что за переменная и в какой именно момент не определена. Есть несколько вариантов решения, но нужно подбирать их с умом, ибо вполне возможно, что после неправильного исправления в одном месте, Вы получите кучу ошибок в других местах.
1. Проверка на определения 1С 8.3
Можно прописать перед ошибкой следующий код:
Если Не НашаПеременная = Неопределено Тогда
Соответственно, закрыв «Если» после, но тут как уже писалось нужно действовать аккуратно, возможно данная конструкция напрочь сломает весь последующий код. Гораздо лучше найти, где объявляется переменная и устранить ошибку.
2. Поиск объявления переменной 1С 8.3
Вполне возможен вариант, что ее просто забыли включить в передаваемые параметры функции или она не доступна в данном виде клиента. Такое случается, когда, например, обращаются из тонкого клиента к метаданным. В этом случае стоит переписать функцию или, возможно, объявить новую, но уже на сервере, которая вернет необходимые тонкому клиенту данные.
3. Обычная опечатка в программе 1С 8.3 Предприятие
Чтобы быстро в программе 1С 8.3 Предприятие проверить опечатка ли спровоцировала ошибку, просто скопируем переменную из объявления и вставим ее имя в то место, где случается ошибка. Можно сделать следующим образом, чтобы избежать таких ошибок в будущем:
Теперь, когда курсор останавливается на идентификаторе, все другие его упоминания будут выделены, как на следующем изображении:
Специалист компании ООО «Кодерлайн»
Дягилев Дмитрий Вадимович
Вас могут заинтересовать следующие статьи:
(0)
У меня есть российский паспорт, но его номер никто не знает, поэтому его номер NULL, а вот те кто родился в 2010 году, еще паспорта не имеют поэтому их номер - пустое значение.
А вот маньяк, гражданин Украины, непонятно есть ли у него гражданство и Российски паспорт, поэтому его номер - неопределенно
те кто родился в 2010 году, еще паспорта не имеют поэтому их номер - NULL
(12) ты всё напутал твой паспорт - Неопределено, у тех, кто родился в 2010 - NULL, у Маньяка - тоже Неопределено
(16) Это не пустое значение, а значение по умолчанию. Хотя обычно, если не ясно, есть что-то или нет, то считается, что нет, а тут наоборот, считается что есть
+ так же нет пустой даты, есть Дата("00010101"), что и является пустой датой.
И т.д. другие грабли.
NULL в Системах управления базами данных (СУБД) — специальное значение (псевдозначение), которое может быть записано в поле таблицы базы данных (БД). NULL соответствует понятию «пустое поле», то есть «поле, не содержащее никакого значения». Введено для того, чтобы различать в полях БД пустые (визуально не отображаемые) значения (например, строку нулевой длины) и отсутствующие значения (когда в поле не записано вообще никакого значения, даже пустого).
Мнение 1: NULL является необходимым и обязательным для любой БД, претендующей на реляционность. В частности без него невозможно корректно построить внешнее соединение (OUTER JOIN) строк из двух таблиц. Именно этой точки зрения придерживался Э. Кодд, явно включив его в качестве третьего из 12 правил для реляционных СУБД. Именно этот принцип закреплен в последних стандартах на язык SQL .
Мнение 2: Значение NULL не требуется, а его использование — следствие ошибки проектирования БД. В базе данных, разработанной в полном соответствии с критериями нормализации, не может быть полей без значений, а значит, не нужно и специальное псевдозначение для таких полей. На практике, однако, из соображений эффективности, нередко оказывается удобным пренебречь некоторыми из правил нормализации, но одним из видов платы за такое пренебрежение является появление пустых полей, для которых и предназначен NULL.
Замечание: нет такого типа - "пустое значение", но есть функция ПустоеЗначение(), которая определяет заполненоность и возвращаеть Истина/Ложь
(0) Пустое значение: "В этот гараж можно поставить что угодно, но ожидается, что в нем должна стоять машина марки Тойота, хотя ее там сейчас нет"
При создании на сервере переменная заполняется ПараметрыФормы = Параметры, отладчик подтверждает, наличие структуры данных.
Но при обращении к переменной из модуля формы, директива &НаСервере, она имеет статус неопределенно.
Пожалуйста подскажите, что я делаю не так?
Скорее всего проблема в самом имени: ПараметрыФормы
Сделайте, например: ПараметрыФормы1
На форме добавьте реквизит (с нужным вам именем и типом) - не элемент.
Это имя будет доступно на клиенте и на сервере во всём модуле формы.
З.Ы. Правда с типами будут ограничения формы.
(3) к сожалению, результат прежний
(2) в моем случае это не подойдет, так как передаются ДанныеФормыСтруктура, проще тогда содержимое вставить в структуру и поместить в временное хранилище.
Но всё же вопрос почему я не вижу значение переменной, или тут проблема исключительно в неподдержиемом формате
(4) При каждом обращении к серверу переменные объявленные на сервере инициализируются заново.
Как вариант поместить код в общий модуль, у которого в свойствах установлен параметр "Повторное использование возвращаемых значений".
(6) ЗначениеВСтрокуВнутр для ДанныеФормыСтруктура, выглядит как , и соответственно ЗначениеИзСтрокиВнутр = неопределенно, с этим работать врядли получится, но идея была не плохая.
(5) за подсказку благодарю, дальше двигаться нет смысла, буду использовать сериализация через переменную формы
Не идея - использовал для обмена между формами.
Можно обойти через ж.
ЗначениеВСтрокуВнутр / ЗначениеИзСтрокиВнутр
(6) Не думаю, что это хороший совет, если есть другие возможные решения.
Конечно в СП уже довольно давно (лет 10?) прилеплено:
Примечание:
Используется для сохранения функциональной совместимости с 1С:Предприятием 7.7. Использовать для других целей не рекомендуется.
Но не известно, когда 1С захочет "выпилить" данные методы.
Не вижу проблемы, как вы предлагали, создать реквизит формы с типом произвольный и сохранять туда значение с типом структура.
ДанныеФормыВЗначение() в помощь.
Но всё же вопрос почему я не вижу значение переменной, или тут проблема исключительно в неподдержиемом формате
представьте что вы у вас не сервер, а кластер из 10 серверов, и вы заранее не знаете на какой сервер попадёт следующий серверный вызов,
соответственно вы не можете хранить контекст на сервере,
на сервере точно есть только данные из базы, на клиенте только то что на форме.
а каждый серверный вызов - это временное окружение, которое удаляется после его завершения.
(8) И даже если один сервер. Может быть открыто несколько идентичных форм одного типа объекта (естественно с разными данными). Для какой формы тогда серверу нужно хранить значения?
Т.е есть возможность существования нескольких клиентских объектов обращающихся к серверу для выполнения одной и той же операции с разными данными.
ну этот пример уж слишком высосан из пальца.
так можно прийти к тому, что повторный (и/или рекурсивный) запуск процедуры сохраняет объявленные внутри неё переменные.
или что сосед может смотреть твою почту, если запустит браузер одновременно.
ну а чо, сервер ведь не знает кто смотрит почту.
(13) И что же такого высосанного в примере, когда пользователь открыл несколько документов или элементов справочника?
Формы будут идентичны, обращения к серверу скорее всего будут за одним и тем же (т.е. вызываемый метод тот же), но с разными данными.
или что сосед может смотреть твою почту, если запустит браузер одновременно.
ну а чо, сервер ведь не знает кто смотрит почту.
Сервер как раз знает кто к нему обращается и зачем. Вот этот пример как раз высосан. Ибо монитор, на котором отображается письмо "вещает" всем, кто оказался в области действия (это уже личное дело каждого смотреть или нет), а сервер отвечает конкретно тому, кто к нему обратился. Другие ответа не увидят.
В вашем примере, должен быть случай, когда на ваше обращение показать письмо пришедшее вам, сервер выдал письмо для другого. Ибо перед этим он запомнил предыдущее обращение в переменной и выдал результат на основании её значения.
И даже если один сервер. Может быть открыто несколько идентичных форм одного типа объекта (естественно с разными данными). Для какой формы тогда серверу нужно хранить значения?
Тут все не так однозначно и сложнее. Каждая форма имеет свой идентификатор, который присваивается при создании формы. У формы есть 2 контекста: клиентский и серверный. И они оба существуют. Так что в рамках контекстного вызова сервер знает с какой
клиентской формы пришел вызов. Мало того, в реквизитах формы могут быть реквизиты, которые недоступны на клиенте, но они сохраняются и при вызовах сервера они не сбрасываются.
Сервер ничего не знает про форму только при внеконтекстном вызове сервера.
Но серверные переменные не сохраняет, для разных вызовов сервера, в любом случае.
(16) Не вижу неоднозначности.
1. Да, каждая форма имеет свой контекст и значения, хранящиеся в реквизитах формы, хранятся в рамках этого контекста. И даже данные объекта формы хранятся именно в реквизите формы (Объект, Отчет, Список и т.д.).
2. Совсем другое дело модуль формы, он един для всех созданных экземпляров форм. Разделение идёт только по директиве компиляции(исполнения). И переменные объявленные в этом модуле также едины для всех экземпляров форм. В отличие от упомянутых выше реквизитов формы и по тем же упомянутым причинам.
3. Контекст (идентификатор и набор данных) формы един как для клиента так и для сервера. Различается лишь набор данных представления этого контекста (то, что нужно только для сервера только там и находится), думаю, по понятной причине попытки минимизации передачи объёма данных при вызове сервера. При вызове серверного метода данные формы вместе с идентификатором передаются на сервер, для актуализации этих данных на нём и их последующем участии в обработке.
4. И да, серверу не передается напрямую (платформой) контекст и данные формы при вызове методов, если указана соответствующая директива для вызываемого метода. Причина та же, что и в предыдущем пункте. А программист определяет нужны ли будут (актуальные) данные с клиента, для обработки данных в вызываемом (реализуемом) методе.
Подытожив, никакие данные не хранятся (дольше необходимого) в модуле формы непосредственно вне контекста этой формы. А переменные объявленные в модуле формы, не важно на клиенте или сервере, не принадлежат её контексту. Т.е. переменная модуля формы объявленная с директивой "на клиенте" существует пока существует форма (которая и может быть получена только на клиенте (и толстый клиент не в счёт)), а переменная объявленная с директивой "на сервере" существует пока существует серверный вызов, а при каждом вызове происходят инициализации таких переменных по умолчанию и прописанная в модуле формы (если таковая инициализация присутствует конечно).
Последнее, кстати, легко проверить самостоятельно, просто добавив в модуль формы строчку присвоения значения этой переменной в модуле формы вне методов и установив на неё точку останова.
И, да. Можно было бы спорить, что разработчики платформы могли сделать сохранение таких переменных для каждого контекста формы пока она существует. Но это бессмысленно, в данном случае на приходится иметь дело с тем что есть. И обсуждать причины, строя догадки, почему они так не сделали (обосновано или нет), тоже бессмысленно.
2. Совсем другое дело модуль формы, он един для всех созданных экземпляров форм. Разделение идёт только по директиве компиляции(исполнения). И переменные объявленные в этом модуле также едины для всех экземпляров форм. В отличие от упомянутых выше реквизитов формы и по тем же упомянутым причинам.
Это совсем не так. Модуль формы это вообще понятие конфигурирования. В контекст будут включены переменные и методы по соответствующим контекстам. Т.е. при компиляции переменные и методы объявленные директивой компиляции &НаКлиент будут включены в клиентский контекст формы, с директивой &НаСервере будут включены в серверный контекст формы. Никакого единого модуля для всех форм не будет. У каждой формы будут свои контексты формы. И Переменные в каждой форме будут свои.
Ну, попробуйте в одной форме присвоить такой переменной значение, а в другой его прочитать.
3. Контекст (идентификатор и набор данных) формы един как для клиента так и для сервера. Различается лишь набор данных представления этого контекста (то, что нужно только для сервера только там и находится), думаю, по понятной причине попытки минимизации передачи объёма данных при вызове сервера. При вызове серверного метода данные формы вместе с идентификатором передаются на сервер, для актуализации этих данных на нём и их последующем участии в обработке.
Контексты формы серверный и клиентский это совсем разные контексты. Для понимания их взаимодействия достаточно понимать общеязыковое взаимодействие клиент-серверной архитектуры.
То, что вы воспринимаете как "Контекст (идентификатор и набор данных) формы един как для клиента так и для сервера" всего лишь сопоставление реквизитов (и т.д.) отдельно на сервере и отдельно на клиенте. С таким успехом можно говорить, что контекст данных 1С и web-сайта тоже один, если настроено соответствие имен и данных. Так что это совершенно разные контексты, со своими возможностями.
Подытожив, никакие данные не хранятся (дольше необходимого) в модуле формы непосредственно вне контекста этой формы.
Очень расплывчатая формулировка. Что значит вне контекста этой формы. Если контекста нет, то и формы нет. Если форма есть, то и контекст есть. Вызов же вне контекста не имеет доступ к контексту.
А переменные объявленные в модуле формы, не важно на клиенте или сервере, не принадлежат её контексту.
А вот тут вы глубоко заблуждаетесь.
Клиентские переменные принадлежат контексту, если объявлены как переменные модуля формы.
Серверные переменные так же принадлежат серверному контексту, просто они не хранят свое значения между серверными вызовами.
Простой пример:
Для клиента:
Присвоили такой переменной значение в клиентском методе. Можем же получить это значение в другом клиентском методе? Можем. Значит такие переменные входят в клиентский контекст.
Для Сервера:
Присвоили значение серверной переменной в серверном методе. Можем получить это значение в том же самом серверном вызове но в другом методе? Может. Значит серверные переменные включаются в серверный контекст.
У каждой формы будут свои контексты формы. И Переменные в каждой форме будут свои.
Ну, попробуйте в одной форме присвоить такой переменной значение, а в другой его прочитать.
Не путайте значения переменных и сами переменные, т.е. их имена и их же инициализация.
Попробую другую аналогию.
Переменные модуля, можно представить как те же переменные метода. Их значения существуют пока не завершится выполнение метода, в котором она объявлена.
Для "клиентской" переменной, она инициализируется, когда форма открывается, и очищается, когда форма закрывается. Т.е. первичный клиентский метод формы, в котором инициализируются объявленные "клиентские" переменные, не завершается до её закрытия, соответственно и значения переменных существуют до этого же события (в независимости от их конкретных значений).
В тоже время первичный серверный метод, в котором инициализируются "серверные" переменные, работает ровно до конца работы вызванного серверного метода и его переменные "живут" соответственно столько же.
Для наглядности, ещё так в рамках языка данного сабжа.
Для первичного события, которое возникает при вызове метода ПолучитьФорму() или любого другого способа, в том числе неявного, когда это делает сама платформа:
В таком случае эти переменные (П1, П2, ИТД) существуют до закрытия формы, неважно явного, из кода (в каком-то методе), или неявного платформой.
Теперь тоже для вызова серверного метода:
Опять же "серверные" переменные "живут" до конца вызова ВызватьМетодСервера(), который завершается почти сразу после исполнения кода вызываемого метода.
Конечно, это лишь упрощенный пример, но картину "жизни" значений переменных модуля он должен дать.
Клиентские переменные принадлежат контексту, если объявлены как переменные модуля формы.
Серверные переменные так же принадлежат серверному контексту, просто они не хранят свое значения между серверными вызовами.
Я прошу прощения, если тут задену поучением, но контекст от латинского "связь". Нет клиентского и серверного контекста, есть контекст формы (данных формы), который связывает данные формы, хранящиеся как на клиенте, так и на сервере. Т.е. данные формы, которые всегда существуют на клиенте (по самому определению её назначения) и их отражение (возможно с дополнением) на сервере, когда это необходимо. Причем сами данные формы первично могут быть частично или полностью отражением данных объекта, хранящегося на сервере.
Соответственно, директива "без контекста" означает, что для получения результата данные связанные с формой не нужны. Иначе бы с директивой "без контекста" можно было бы получить доступ к данным формы на сервере. "Серверный контекст" по вашему же на сервере есть, так почему бы и нет?
Т.е. директива "без контекста" в первую очередь определяет, нужно ли "тащить" актуальные данные формы с клиента на сервер, а не просто возможность "достучаться" до них там, на сервере. Как я уже писал ранее, это попытка минимизировать сетевой трафик между клиентом и сервером, а не разграничения доступа.
Присвоили такой переменной значение в клиентском методе. Можем же получить это значение в другом клиентском методе? Можем. Значит такие переменные входят в клиентский контекст.
Опять таки вы путаете область видимости с инициализацией. Инициализируются такие переменные один раз для сервера и для клиента.
Для клиента один раз при создании формы и существуют, пока существует форма. К контексту они не привязаны, просто существуют вместе с ним, и на сервер соответственно вместе с контекстом не передаются.
Для сервера же такие переменные инициализируются один раз, но при каждом вызове его метода с клиента ( пример смотреть выше ).
Для Сервера:
Присвоили значение серверной переменной в серверном методе. Можем получить это значение в том же самом серверном вызове но в другом методе? Может. Значит серверные переменные включаются в серверный контекст.
Если бы было именно так, то значения переменных как раз не терялись бы после завершения работы серверного метода. Т.к. по вашему же существует некий "серверный контекст", а значит его данные, не имеющие своего отражения на клиенте (или наоборот, кому как удобно), не должны исчезать (повторно инициализироваться) пока он существует при каждом серверном вызове метода с клиента.
Здравствуйте, коллеги! Сегодня поговорим о проблеме неопределенных переменных в 1С. Рядовой пользователь с данной ошибкой сталкиваться не должен, но если уж и произошло подобное при работе в типовой конфигурации 1С, которая никак не модифицировалась, возможно, у нас наклевывается проблема самого релиза, которая иссякнет при обновлении. В таком случае стоит связаться со специалистом, чтобы найти выход из ситуации.
Если же Вы сами занимаетесь разработкой и столкнулись с ошибкой, «Переменная не определена в 1С», то следует обратится к конфигуратору, найти, что за переменная и в какой именно момент не определена. Есть несколько вариантов решения, но нужно подбирать их с умом, ибо вполне возможно, что после неправильного исправления в одном месте, Вы получите кучу ошибок в других местах.
1. Проверка на определения 1С 8.3
Можно прописать перед ошибкой следующий код:
Если Не НашаПеременная = Неопределено Тогда
Соответственно, закрыв «Если» после, но тут как уже писалось нужно действовать аккуратно, возможно данная конструкция напрочь сломает весь последующий код. Гораздо лучше найти, где объявляется переменная и устранить ошибку.
2. Поиск объявления переменной 1С 8.3
Вполне возможен вариант, что ее просто забыли включить в передаваемые параметры функции или она не доступна в данном виде клиента. Такое случается, когда, например, обращаются из тонкого клиента к метаданным. В этом случае стоит переписать функцию или, возможно, объявить новую, но уже на сервере, которая вернет необходимые тонкому клиенту данные.
3. Обычная опечатка в программе 1С 8.3 Предприятие
Чтобы быстро в программе 1С 8.3 Предприятие проверить опечатка ли спровоцировала ошибку, просто скопируем переменную из объявления и вставим ее имя в то место, где случается ошибка. Можно сделать следующим образом, чтобы избежать таких ошибок в будущем:
Теперь, когда курсор останавливается на идентификаторе, все другие его упоминания будут выделены, как на следующем изображении:
Специалист компании ООО «Кодерлайн»
Дягилев Дмитрий Вадимович
Вас могут заинтересовать следующие статьи:
Здравствуйте, коллеги! Сегодня поговорим о проблеме неопределенных переменных в 1С. Рядовой пользователь с данной ошибкой сталкиваться не должен, но если уж и произошло подобное при работе в типовой конфигурации 1С, которая никак не модифицировалась, возможно, у нас наклевывается проблема самого релиза, которая иссякнет при обновлении. В таком случае стоит связаться со специалистом, чтобы найти выход из ситуации.
Если же Вы сами занимаетесь разработкой и столкнулись с ошибкой, «Переменная не определена в 1С», то следует обратится к конфигуратору, найти, что за переменная и в какой именно момент не определена. Есть несколько вариантов решения, но нужно подбирать их с умом, ибо вполне возможно, что после неправильного исправления в одном месте, Вы получите кучу ошибок в других местах.
1. Проверка на определения 1С 8.3
Можно прописать перед ошибкой следующий код:
Если Не НашаПеременная = Неопределено Тогда
Соответственно, закрыв «Если» после, но тут как уже писалось нужно действовать аккуратно, возможно данная конструкция напрочь сломает весь последующий код. Гораздо лучше найти, где объявляется переменная и устранить ошибку.
2. Поиск объявления переменной 1С 8.3
Вполне возможен вариант, что ее просто забыли включить в передаваемые параметры функции или она не доступна в данном виде клиента. Такое случается, когда, например, обращаются из тонкого клиента к метаданным. В этом случае стоит переписать функцию или, возможно, объявить новую, но уже на сервере, которая вернет необходимые тонкому клиенту данные.
3. Обычная опечатка в программе 1С 8.3 Предприятие
Чтобы быстро в программе 1С 8.3 Предприятие проверить опечатка ли спровоцировала ошибку, просто скопируем переменную из объявления и вставим ее имя в то место, где случается ошибка. Можно сделать следующим образом, чтобы избежать таких ошибок в будущем:
Теперь, когда курсор останавливается на идентификаторе, все другие его упоминания будут выделены, как на следующем изображении:
Специалист компании ООО «Кодерлайн»
Дягилев Дмитрий Вадимович
Вас могут заинтересовать следующие статьи:
Читайте также: