Имя: Пароль:
1C
1С v8
v8: Как обратиться к метаданным документа в УФ?
0 svchernova
 
09.11.11
12:57
Разрабатываю документ для тонкого клиента.
Хочу обратиться к метаданным.
&НаСервере
Процедура ПроверитьНомер(Объект, НачальнаяДатаДокумента)
   // Определяем назначенную для данного вида документов периодичность смены номера
   ПериодСменыНомера = Объект.Метаданные().ПериодичностьНомера;

Ругается:
{Документ.Страхование.Форма.ФормаДокументаУпр.Форма(626)}: Метод объекта не обнаружен (Метаданные)
   ПериодСменыНомера = Объект.Метаданные().ПериодичностьНомера;

Как обратиться к метаданным документа в моём случае?
1 DrShad
 
09.11.11
13:01
Метаданные (Metadata)
Синтаксис:

Метаданные()
Возвращаемое значение:

Тип: ОбъектМетаданных: Справочник.

Описание:

Предоставляет доступ к объекту описания метаданных справочника. Другой путь получения того же значения - через свойство глобального контекста Метаданные. Например: Метаданные.Справочники.Номенклатура.

Доступность:

Сервер, толстый клиент, внешнее соединение
2 Mort
 
09.11.11
13:02
Объект.Ссылка.Метаданные() как вариант
3 Поручик
 
09.11.11
13:03
(1) Пальцем в  }|{опу

(0) Объект.Ссылка.Метаданные() хорошо работает.
4 svchernova
 
09.11.11
13:10
(2) и (3) Спасибо :) Это сработало. Пытаюсь обработать смену даты документа и проверить его номер.

На тонком клиенте  ошибка

{Документ.Страхование.Форма.ФормаДокументаУпр.Форма(619)}: Ошибка при установке значения атрибута контекста (Объект)
   ПроверитьНомер(Объект, мТекущаяДатаДокумента);    
по причине:
Нельзя изменять поле, содержащее объект данных формы

Уже совсем крыша съехала у меня.
5 5 Элемент
 
09.11.11
13:12
Процедура ПроверитьНомер(Знач Объект, Дата)
6 svchernova
 
09.11.11
13:14
(5) я же должна сначала дату проверить. Аналогично тому как работала процедура
РаботаСДиалогами.ПроверитьНомерДокумента(Объект, мТекущаяДатаДокумента);
7 GROOVY
 
модератор
09.11.11
13:18
Объект в форме это ДанныеФормы, Не надо их никуда передавать. Передавайте сам объект: РеквизитФормыВЗначение()
8 svchernova
 
09.11.11
13:25
(7) Чёрт возьми. Меня. Не понимаю! Я просто пытаюсь интерактивно поменять дату документа. На событие "При изменении" Даты документа навесила процедуру

Процедура ПроверитьНомер(Объект, НачальнаяДатаДокумента)
   // Определяем назначенную для данного вида документов периодичность смены номера
   ПериодСменыНомера = Объект.Ссылка.Метаданные().ПериодичностьНомера;

   //В зависимости от установленной периодичности смены номеров,
   //определяем разность старой и новой датами документа.
   Если ПериодСменыНомера = Метаданные.СвойстваОбъектов.ПериодичностьНомераДокумента.Год Тогда
       РазностьДат = НачалоГода(НачальнаяДатаДокумента) - НачалоГода(Объект.Дата);

   ИначеЕсли ПериодСменыНомера = Метаданные.СвойстваОбъектов.ПериодичностьНомераДокумента.Квартал Тогда
       РазностьДат = НачалоКвартала(НачальнаяДатаДокумента) - НачалоКвартала(Объект.Дата);

   ИначеЕсли ПериодСменыНомера = Метаданные.СвойстваОбъектов.ПериодичностьНомераДокумента.Месяц Тогда
       РазностьДат = НачалоМесяца(НачальнаяДатаДокумента) - НачалоМесяца(Объект.Дата);

   ИначеЕсли ПериодСменыНомера = Метаданные.СвойстваОбъектов.ПериодичностьНомераДокумента.День Тогда
       РазностьДат = НачальнаяДатаДокумента - Объект.Дата;

   Иначе
       Возврат;

   КонецЕсли;

   Если РазностьДат <> 0 Тогда
       Объект.Номер = "";
   КонецЕсли;
КонецПроцедуры

Вываливает сообщение "Нельзя изменять поле, содержащее объект данных формы ".
9 svchernova
 
09.11.11
13:27
(7) Период смены номера у меня = год, и РазностьДат = 0. Вроде как должна поменяться дата.. без пробле. Нет, откуда-то вылазит ошибка, какчерт из табакерки
10 GROOVY
 
09.11.11
13:28
Хотя гонять объект туда-сюда ради проверки даты - это извращение. Переписывайте свою процедуру ПроверитьНомер().
11 svchernova
 
09.11.11
13:32
(10) Может быть, после Ваших лекций перестану быть извращенкой.Пока могу только категориями толстого клиента мыслить.
12 svchernova
 
09.11.11
14:05
Нельзя изменять поле, содержащее объект данных формы. А если мне нужно изменить дату документа..
13 Поручик
 
09.11.11
14:15
(12) Посмотреть, как реализовано в типовых не предлагать? Или во франях принято изобретать лисапеды?
14 svchernova
 
09.11.11
14:20
(13) в типовой, которая у меня есть, нет управляемых форм.
15 Mort
 
09.11.11
14:22
(12) По-хорошему, процедура не должна копаться во внутренностях своих параметров.
Плюс в этой задаче нет ничего такого, что бы потребовало участие сервера - кроме выяснения периодичности документа, которое можно сделать, например сразу при создании на сервере и запомнить в какой-нить реквизит подходящего типа. Для простоты примера в строковой:

&НаСервере
Процедура ПриСозданииНаСервере()
// реквизит формы
ПериодичностьНомераСтрокой = Строка(Объект.Ссылка.Метаданные().ПериодичностьНомера);


&НаКлиенте
Процедура ДатаПриИзменении(Элемент)
Если ИзменилсяПериодДаты(ПериодичностьНомераСтрокой, СтараяДата, НоваяДата) Тогда
Номер = "";
КонецЕсли;
....


Где-то на клиенте:
Процедура ИзменилсяПериодДаты(ПериодичностьНомераСтрокой, СтараяДата, НоваяДата) Экспорт
Если ПериодичностьНомераСтрокой = "год" Тогда
....

и т.д.
16 Mort
 
09.11.11
14:24
+(15) Собсна если пользователи меняют дату раз в день, кэшировать такое значение не имеет смысла. Просто привел как пример того, что можно обойтись без вызова сервера.
17 svchernova
 
09.11.11
14:29
(16) Знаешь, что до меня оеально не доходит? (Ответ "Ничего" - не самый правильный, я начала понимать немножко). Я не понимаю, в каком месте своего кода я "Вызываю сервер"

&НаКлиенте
Процедура ДатаПриИзменении(Элемент)
   мТекущаяДатаДокумента = Объект.Дата;
   ПроверитьНомер(Объект, мТекущаяДатаДокумента);    
КонецПроцедуры

&НаСервере
Процедура ПроверитьНомер(Объект, НачальнаяДатаДокумента)
   // Определяем назначенную для данного вида документов периодичность смены номера
   ПериодСменыНомера = Объект.Ссылка.Метаданные().ПериодичностьНомера;
   Документ = РеквизитФормыВЗначение("Объект");

   //В зависимости от установленной периодичности смены номеров,
   //определяем разность старой и новой датами документа.
   Если ПериодСменыНомера = Метаданные.СвойстваОбъектов.ПериодичностьНомераДокумента.Год Тогда
       РазностьДат = НачалоГода(НачальнаяДатаДокумента) - НачалоГода(Объект.Дата);

   ИначеЕсли ПериодСменыНомера = Метаданные.СвойстваОбъектов.ПериодичностьНомераДокумента.Квартал Тогда
       РазностьДат = НачалоКвартала(НачальнаяДатаДокумента) - НачалоКвартала(Объект.Дата);

   ИначеЕсли ПериодСменыНомера = Метаданные.СвойстваОбъектов.ПериодичностьНомераДокумента.Месяц Тогда
       РазностьДат = НачалоМесяца(НачальнаяДатаДокумента) - НачалоМесяца(Объект.Дата);

   ИначеЕсли ПериодСменыНомера = Метаданные.СвойстваОбъектов.ПериодичностьНомераДокумента.День Тогда
       РазностьДат = НачальнаяДатаДокумента - Объект.Дата;

   Иначе
       Возврат;

   КонецЕсли;

   Если РазностьДат <> 0 Тогда
       Объект.Номер = "";
   КонецЕсли;
КонецПроцедуры
18 hhhh
 
09.11.11
14:33
(17) ну

&НаСервере

или эту строчку не ты написала?
19 svchernova
 
09.11.11
14:34
(18) я написала. Но даже если я всё тело процедуры закомментирую, то ошибка всё равно вываливается
20 Mort
 
09.11.11
14:34
(17) ПроверитьНомер(Объект, мТекущаяДатаДокумента);  - вызывает функцию на сервере. Поскольку директива &наСервере (а не &НаСервереБезКонтекста), у тебя вся форма прется на сервер и объект передавать не нужно, он там и так будет. Но так делать неправильно.
21 Mort
 
09.11.11
14:36
в (15) нужно Функция ИзменилсяПериодДаты(... но это как я понял не волнует.
22 Mort
 
09.11.11
14:38
И ещё, вот тут

&НаКлиенте
Процедура ДатаПриИзменении(Элемент)
   мТекущаяДатаДокумента = Объект.Дата;
   ПроверитьНомер(Объект, мТекущаяДатаДокумента);    
КонецПроцедуры

дата уже изменена. Сравнивать её с самой собою можно, но не рекомендуется. Сделай реквизит формы СтараяДата и там храни старое значение.
23 svchernova
 
09.11.11
14:38
(21) Начинает доходить.. Славатегосподи. Твоя функция как раз-таки взволновала до крайности :))) Я начала её писать :))
24 svchernova
 
09.11.11
14:39
(22) Спасибо тебе.
25 svchernova
 
09.11.11
14:43
(22) Вот ведь действительно ерундень написала
26 svchernova
 
09.11.11
14:51
(22) Морт, ты там?
27 Mort
 
09.11.11
15:31
Угу
28 acsent
 
09.11.11
15:34
Объект - это совсем не тот объект
29 acsent
 
09.11.11
15:35
(0) Прочитай для начала книжку по УФ
30 acsent
 
09.11.11
15:35
а то так задолбаешь всех своими нубскими вопросами
31 svchernova
 
09.11.11
15:53
(26) Ты понимаешь, в чем дело. я о твоём примере. Переменная ПериодичностьНомераСтрокой определяется на сервере. Но затем эта переменная используется в процедуре

&НаКлиенте
Процедура ДатаПриИзменении(Элемент)
Если ИзменилсяПериодДаты(ПериодичностьНомераСтрокой, СтараяДата, НоваяДата) Тогда
Номер = "";
КонецЕсли;

И её не видно на клиенте.
32 Mort
 
09.11.11
15:54
(31) Поэтому я написал над инициализацией "// реквизит формы"
33 svchernova
 
09.11.11
15:54
(30) Уже всех задолбала.. начала лекции Чистова слушать, но на это нужно время.
34 svchernova
 
09.11.11
15:56
(32) Вон как.. Получается, что ВСЕ переменные, которые будут использоваться как на клиенте, так и на сервере, нужно прописать в реквизитах формы, правильно?
35 Mort
 
09.11.11
16:04
Ну в общем случае да.
36 svchernova
 
09.11.11
16:06
(35) Спасибо тебе.
37 svchernova
 
09.11.11
16:09
(29) и (30) а тебе только позавидовать можно. Стаж 6 лет и времени вагон, все книжки прочесть успел. и вопросов нубских не задаёшь. умница.
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший