Имя: Пароль:
1C
1C 7.7
v7: Псевдореквизиты в документе 7.7
,
0 Franchiser
 
гуру
20.06.20
23:19
Планируется создать справочник вида документ, рекв1, рекв2, рекв3 и т.д. По типу доп. свойств 1с8.
В документе нужно отображать/изменять указанные псевдореквизиты. Есть готовое решение?
1 Злопчинский
 
20.06.20
23:23
конкретнее. Зачем?
если реквизиты описательные - то в "комментарий".
2 Злопчинский
 
20.06.20
23:24
все равно получится типа ПВХ. документ-тип-видреквизита-значениереквизита.
.
но это - промахи причем глобальные в архитектуре.
а если описательно - см.(1)
3 Franchiser
 
гуру
20.06.20
23:27
Для экономии места: большой объем таблицы документов и таблицы журнала. Будут кастомные индексы для ускорения поиска. Вообще идея не моя, я тоже против.
4 Franchiser
 
гуру
20.06.20
23:28
(2) пока речь о добавлении 1-го рекаизита, в будущем может быть ещё.
5 Franchiser
 
гуру
20.06.20
23:30
(2) нет пока планируется справочник

Юр. Лицо, документ, рекв типа дата
6 Кулибин
 
20.06.20
23:35
Когда при такой вводной спрашивают про некое "готовое решение", это вызывает сложную гамму эмоций. Как человек, имеющий серты по 7.0, 7.5 и 7.5 (расставьте виды учетов, кто как сможет), скажу: возможно почти всё.
7 Franchiser
 
гуру
20.06.20
23:37
(3) реструктуризация базы добавлении 1 реквизита занимает около суток, рост базы несколько десятков гигабайт при этом.
8 Franchiser
 
гуру
20.06.20
23:39
(6) я думал в типовой или в самописках где такое встречается. Типа записываешь документ, и в какой то справочник добавляется значение или обновляется.
9 Franchiser
 
гуру
20.06.20
23:42
(6) вообще какие минусы такого подхода.
10 Злопчинский
 
20.06.20
23:46
(4) база на скуле.
наверное при таких объемах правильнее будет реструктуризацию проводить прямо на скуле, ручками править словарь и подсовывать.. типа так?
11 Кулибин
 
20.06.20
23:47
(8) в 7.7, при знании конфы и платформы, ни одна тактическая задача вообще не требует времени на осмысление и практически не требует времени на реализацию, нужно записывать и обновлять - записывай и обновляй, но неизбежно будут разбежки - нужен пост сканер. И ещё: то, либо, нибудь и кое пишутся через дефис - это азы хорошего программирования на 1с 7.х.
12 Franchiser
 
гуру
20.06.20
23:48
(10) средствами 1с делаю, не пробовал как в скуле делать реструктуризацию. Но объем базы растет.
13 Franchiser
 
гуру
20.06.20
23:49
Вообще поставлена задача хранить реквизиты в этом отдельном справочнике. Какие аргументы против?
14 Злопчинский
 
20.06.20
23:50
(8) "Типа записываешь документ, и в какой то справочник добавляется значение или обновляется." - в урбд добавляется...
15 Franchiser
 
гуру
20.06.20
23:51
(14) урбд это компонента, мне нужен код на 1с и пример с отображением на форме.
16 Franchiser
 
гуру
20.06.20
23:52
(15) +Что то похожее есть в типовых?
17 Злопчинский
 
20.06.20
23:53
(13) против - корявая именно сама идея. Реализация этоq хрени неминуемо приведет к тому, что реквизиты будут плодить направо и налево и это выйдет из-под контроля. и превратится в обычное хранилище нетипизированной информации. Зачем ждать наступления жопы? не проще ее сделать сразу?

имхо ясен пень
18 Franchiser
 
гуру
20.06.20
23:55
(17) ну понятно, проблема контроля есть, о чем сообщил
19 Franchiser
 
гуру
20.06.20
23:57
(17) что будет с блокировками? Когда эти документы будут в транзакции записывать в справочник?
20 Злопчинский
 
21.06.20
00:05
(19) смотря как организовать работу с этими допреквизитами.
21 Franchiser
 
гуру
21.06.20
00:06
Увеличится время записи при импорте: придется проверять наличие элементов в этом справочнике и чистить реквизиты или обновлять.
22 Злопчинский
 
21.06.20
00:08
(21) если про импорт только, тогда сделать однопользовательский доступ. очередью и ее обслуживанием типа. и никаких транзакций
23 Franchiser
 
гуру
21.06.20
00:10
Нет документы создаются с этим реквизитами пользователями, они могут и исправить из в документе, но если проимпортировали то нужно почистить реквизит.
24 Cthulhu
 
21.06.20
00:13
не надо
25 Franchiser
 
гуру
21.06.20
00:16
(24) нужен список аргументов чем больше тем лучше
26 Cthulhu
 
21.06.20
02:18
(25): принцип бритвы оккама.
и любое разделение любой единой сущности (документ) на куски - неизбежно(!) влечет проблемы.
а твоя позиция - она напоминает "хочу отрезать жене ноги - не помещается в кровать. а когда будет вставать - будет пристегивать протезы... нужен сисок аргументов "против" чем больше тем лучше".
не. надо. точка.
проблемы с производительностью - решаются другими способами.
27 Djelf
 
21.06.20
09:37
(0) В Скате сделано https://www.33lab.ru/load/viewcategory/4.html
Там для чего угодно произвольные характеристики делаются.
Только по быстрому ты это не не вытащишь,  там не один модуль потребуется.
28 Djelf
 
21.06.20
09:45
+(27) Вот так это выглядит https://gyazo.com/251891ff088a767cad1e83460a60b20f
29 Franchiser
 
гуру
21.06.20
10:51
(28) да, прикольно, но хотелось бы что-то попроще
30 Djelf
 
21.06.20
11:26
(29) Это поначалу кажется что проще - лучше.
Как только сделаешь попроще, так и хотелки на посложнее подтянутся.
Структуру хранилища возьми, оно универсально. И на нем сделай попроще. Переделывать потом меньше придется.
Ну и древние статьи на похожую тему в помощь:
https://old.mista.ru/articles1c/hare/article.74.html
https://old.mista.ru/articles1c/hare/article.27.html
31 Franchiser
 
гуру
21.06.20
21:55
(30) почитаю, спасибо. Я понял, надо было искать поиском квази-ревизиты.
32 Сияющий Асинхраль
 
21.06.20
22:33
(0) Вот, например, вариант хранения нескольких табличных частей в семерке.

http://catalog.mista.ru/public/825458/

Работает как часы. Хотя делать подобное для реквизитов шапки мне бы даже в голову не пришло, ибо нахрен не надо...
33 Cthulhu
 
22.06.20
01:29
(32) доп. документ для второй таб.части - хреновая идея. общий журнал без отборов будет с мусором, а сложных отборов в 7-ке нету. опробованы все варианты, в итоге оптимальной бала признана избыточная "композитная" табличная часть. все данные в одном объекте (документе). в диалоге прекрасно распихивается по закладкам, на каждой - свой состав видимых колонок (внешний вид настраивается стандартно в конфигураторе) и свой перечень строк. вариант автору точно не подойдет, т.к. это не экономит объем данных мета-объекта. работает как часы, не надо никаких доп.кнопок и лишних операций по вводу данных в ТЗ на морде, стандартная корректировка табличной части.
34 Cthulhu
 
22.06.20
01:31
(33)+: ну и более двух таб.частей можно (в варианте по ссылке в (32) и (30) вроде только вторая таб.часть по ссылке на служебный документ в реквизите шапки).
35 Bigbro
 
22.06.20
04:26
(3) что значит для экономии места? реквизит строковый длиной сто символов займет одинаковое место в документе или в справочнике, только если городить огороды с костылями и куда то реквизиты выносить отдельно - потребуется доп нагрузка на всю эту синхронизацию, передачу данных туда-сюда, проверки целостности и т.п.
плюсы пока неясны.
конечно если этот реквизит будет встречаться у одного документа из тысячи, а самих разных реквизитов сотни - то можно и сделать.
но пока задача вроде звучит иначе.
36 Franchiser
 
гуру
22.06.20
10:04
(35) в конфигурации один документ только, документов много, новый реквизит будет заполненный только в менее чем в 0.000001% случаев.
37 73с
 
22.06.20
10:35
В КАМИН 1.2 есть хранение реквизитов документа в документе другого вида, наверно по аналогии можно и справочник привязать
38 Bigbro
 
22.06.20
10:44
(36) тогда норм, пилите, если база прямо гигантская - ну прямые запросы прикрутите в конце концов.
39 VladZ
 
22.06.20
11:02
(0) В любой замкнутой системе уровень энтропии возрастает.
Как следствие, уровень хаоса в системе нужно:
- как минимум, контролировать
- как максимум, минимизировать.

Применительно к специалисту 1С: не допускать критичного уровня хаоса в конфигурациях 1С.

Итак, смотрим на нашу задачу. Повышает уровень хаоса? Повышает!
Сразу "Ф топку!".
40 ADirks
 
22.06.20
13:41
(0) если база на скуле, то проще свою табличку сделать, и индексировать её как занравится
типа:
    ТекстЗапроса_Таблица = "Set NoCount ON
    |CREATE TABLE ДополнительныеРеквизитыОбъектов (
    |    Объект char(13) Not Null,
    |    Имя varchar(256) Not Null,
    |    Тип varchar(256) Not Null,
    |    Значение_Ссылка char(13),
    |    Значение_Число Numeric(19, 3),
    |    Значение_Строка varchar(256),
    |    Значение_Дата DateTime
    |)
    |";
    
    ТекстЗапроса_Индексы = "
    |CREATE INDEX ОбъектИмя ON ДополнительныеРеквизитыОбъектов(Объект, Имя)
    |";


// полный текст класса, для пущего понту
//==============================


//#if _NOW_PREPARE_CLASS
Перем Форма, ВыбОбъект, ВыбДок, ВыбИмяФлага; //чтобы синтакс-контроль не ругался каждый раз

Перем зпрПолучить;

Перем Конт;
Перем ОбъектВладелец;
Перем тзРекв;

//#else
Перем оДопРекв;
Перем тпДопРекв;
Перем тпФлаги;
Перем оПривязки;
//#endif

//#if _NOW_PREPARE_CLASS

///******************************** ADirks 31.05.2013 ************
Функция СоздатьТаблицу() Экспорт
    ТекстЗапроса_Таблица = "Set NoCount ON
    |CREATE TABLE ДополнительныеРеквизитыОбъектов (
    |    Объект char(13) Not Null,
    |    Имя varchar(256) Not Null,
    |    Тип varchar(256) Not Null,
    |    Значение_Ссылка char(13),
    |    Значение_Число Numeric(19, 3),
    |    Значение_Строка varchar(256),
    |    Значение_Дата DateTime
    |)
    |";
    
    ТекстЗапроса_Индексы = "
    |CREATE INDEX ОбъектИмя ON ДополнительныеРеквизитыОбъектов(Объект, Имя)
    |";
    
    оБД = СоздатьОбъект("ТБазаДанных");
    Если оБД.СоздатьТаблицу("ДополнительныеРеквизитыОбъектов", ТекстЗапроса_Таблица, ТекстЗапроса_Индексы) <> 1 Тогда
        Возврат 0;
    КонецЕсли;
    
    Возврат 1;
КонецФункции
///******************************** ADirks 31.05.2013 ************

///******************************** ADirks 07.06.2013 ************
Функция Объект()
    Попытка
        Возврат Конт.ТекущийЭлемент();
    Исключение
    КонецПопытки;

    Попытка
        Возврат Конт.ТекущийДокумент();
    Исключение
    КонецПопытки;
    
    Возврат "";
КонецФункции
///******************************** ADirks 07.06.2013 ************

///******************************** ADirks 05.12.2012 ************
Процедура Инит(_Конт, Знач _Объект = "") Экспорт
    Сам = Сам(Контекст);
    
    Конт = _Конт;
    ОбъектВладелец = _Объект;
    Если ОбъектВладелец = "" Тогда
        ОбъектВладелец = Объект();
    КонецЕсли;
    
    тзРекв = СоздатьОбъект("ТаблицаЗначений");
    тзРекв.НоваяКолонка("Имя", "Строка");
    тзРекв.НоваяКолонка("Тип", "Строка");
    тзРекв.НоваяКолонка("фЭтоГалка", "Число");
    
    Сам.ПолучитьБазовыйКласс().Инит(_Конт);
КонецПроцедуры
///******************************** ADirks 05.12.2012 ************

///******************************** ADirks 05.12.2012 ************
Процедура ДобавитьГалку(Имя) Экспорт
    Если НайтиСтрокуТЗ(тзРекв, "Имя", Имя) = 0 Тогда
        тзРекв.НоваяСтрока();
        тзРекв.Имя = Имя;
    КонецЕсли;
    тзРекв.Тип = "Число";
    тзРекв.фЭтоГалка = 1;
КонецПроцедуры

Процедура Добавить(Имя, Тип) Экспорт
    Если НайтиСтрокуТЗ(тзРекв, "Имя", Имя) = 0 Тогда
        тзРекв.НоваяСтрока();
        тзРекв.Имя = Имя;
    КонецЕсли;
    тзРекв.Тип = Тип;
КонецПроцедуры
///******************************** ADirks 05.12.2012 ************

///******************************** ADirks 18.12.2012 ************
Процедура ДобавитьЧисло(Имя) Экспорт
    Если НайтиСтрокуТЗ(тзРекв, "Имя", Имя) = 0 Тогда
        тзРекв.НоваяСтрока();
        тзРекв.Имя = Имя;
    КонецЕсли;
    тзРекв.Тип = "Число";
КонецПроцедуры
///******************************** ADirks 18.12.2012 ************


///******************************** ADirks 05.12.2012 ************
Функция _ПриОткрытии() Экспорт
    Сам = Сам(Контекст);
    Если ПустоеЗначение(ОбъектВладелец) = 1 Тогда
        ОбъектВладелец = Объект();
    КонецЕсли;
    
    тзРекв.ВыбратьСтроки();
    Пока тзРекв.ПолучитьСтроку() = 1 Цикл
        Имя = тзРекв.Имя;
        м = Фаб.Модуль(Конт, "Функция Установить(Зн)
        |    "+Имя+" = Зн;
        |КонецФункции");
        
        Значение = Сам.Получить(ОбъектВладелец, Имя);
        
        м.Установить(Значение);
    КонецЦикла;
    
    Возврат 1;
КонецФункции
///******************************** ADirks 05.12.2012 ************

///******************************** ADirks 07.06.2013 ************
Функция фНадоЗаписать()
    тзРекв.ВыбратьСтроки();
    Пока тзРекв.ПолучитьСтроку() = 1 Цикл
        Имя = тзРекв.Имя;
        м = Фаб.Модуль(Конт, "Функция Получить()
        |    Возврат "+Имя+";
        |КонецФункции");
        Значение = м.Получить();
        
        Если ПустоеЗначение(Значение) = 0 Тогда
            Возврат 1;
        КонецЕсли;
    КонецЦикла;
    
    Возврат 0;
КонецФункции
///******************************** ADirks 07.06.2013 ************

///******************************** ADirks 05.12.2012 ************
Функция _ПриЗаписи() Экспорт
    Сам = Сам(Контекст);
    Если ПустоеЗначение(ОбъектВладелец) = 1 Тогда
        Если фНадоЗаписать() = 1 Тогда
            Конт.Записать(); //инииппёт
            ОбъектВладелец = Объект();
        КонецЕсли;
    КонецЕсли;
    
    тзРекв.ВыбратьСтроки();
    Пока тзРекв.ПолучитьСтроку() = 1 Цикл
        Имя = тзРекв.Имя;
        м = Фаб.Модуль(Конт, "Функция Получить()
        |    Возврат "+Имя+";
        |КонецФункции");
        Значение = м.Получить();
        
        Если ПустоеЗначение(Значение) = 1 Тогда
            Если ПустоеЗначение(ОбъектВладелец) <> 1 Тогда
                Сам.Удалить(ОбъектВладелец, Имя);
            КонецЕсли;
        Иначе
            Сам.Установить(ОбъектВладелец, Имя, Значение);
        КонецЕсли;
    КонецЦикла;
    
    Возврат 1;
КонецФункции
///******************************** ADirks 05.12.2012 ************

///******************************** ADirks 17.09.2012 ************
Функция Получить(Объект, Имя, Комментарий = "") Экспорт
    Если ТипЗначения(Объект) = 2 Тогда
        идОбъект = Объект;
    Иначе
        идОбъект = РадугаСервис.ЗначениеВДлиннуюСтрокуБД(Объект);
    КонецЕсли;
    
    Если зпрПолучить = Неопределено Тогда
        ТекстЗапроса = "Set NoCount ON
        |SELECT
        |    Рекв.Тип,
        |    Рекв.Значение_Ссылка,
        |    Рекв.Значение_Число,
        |    Рекв.Значение_Строка,
        |    Рекв.Значение_Дата
        |FROM
        |    ДополнительныеРеквизитыОбъектов Рекв (NoLock)
        |WHERE
        |    Рекв.Объект = ?
        |    AND Рекв.Имя = ?
        |";
        зпрПолучить = СоздатьОбъект("ODBCRecordSet");
        зпрПолучить.Подготовить(ТекстЗапроса);
        зпрПолучить.ДобПараметр(1, 14, 13, 0);
        зпрПолучить.ДобПараметр(1, 15, 256, 0);
    КонецЕсли;
    
    зпрПолучить.УстПараметр(1, идОбъект);
    зпрПолучить.УстПараметр(2, Имя);
    стЗнач = зпрПолучить.ВыполнитьСкалярный();
    
    
    //ТекстЗапроса = "Set NoCount ON
    //|SELECT
    //|    Рекв.Тип,
    //|    Рекв.Значение_Ссылка,
    //|    Рекв.Значение_Число,
    //|    Рекв.Значение_Строка,
    //|    Рекв.Значение_Дата
    //|FROM
    //|    ДополнительныеРеквизитыОбъектов Рекв (NoLock)
    //|WHERE
    //|    Рекв.Объект = '"+идОбъект+"'
    //|    AND Рекв.Имя = '"+Имя+"'
    //|";
    //стЗнач = ЗапросСКЛ.ВыполнитьСкалярный(ТекстЗапроса);
    
    Тип = стЗнач.Тип;
    Если Тип = Неопределено Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    Вид = "";
    нПоз = Найти(стЗнач.Тип, ".");
    Если нПоз > 0 Тогда
        Вид = Сред(Тип, нПоз+1);
        Тип = Лев(Тип, нПоз-1);
    КонецЕсли;
    
    Если Тип <> "Строка" Тогда
        Комментарий = СокрЛП(стЗнач.Значение_Строка);
    КонецЕсли;
    
    Если Тип = "Число" Тогда
        Возврат стЗнач.Значение_Число;
    ИначеЕсли Тип = "Строка" Тогда
        Возврат стЗнач.Значение_Строка;
    ИначеЕсли Тип = "Дата" Тогда
        Возврат стЗнач.Значение_Дата;
    ИначеЕсли Тип = "Документ" Тогда
        Возврат РадугаСервис.ЗначениеИзДлиннойСтрокиБД("Документ", стЗнач.Значение_Ссылка);
    ИначеЕсли Тип = "Справочник" Тогда
        Возврат РадугаСервис.ЗначениеИзДлиннойСтрокиБД("Справочник", стЗнач.Значение_Ссылка);
    ИначеЕсли Тип = "Перечисление" Тогда
        Возврат РадугаСервис.ЗначениеИзДлиннойСтрокиБД("Перечисление", стЗнач.Значение_Ссылка);
    КонецЕсли;
КонецФункции
///******************************** ADirks 17.09.2012 ************

///******************************** ADirks 14.07.2016 ************
Функция тзп_Значение(Выражение_идОбъект13, Имя, Тип) Экспорт
    Если Тип = "Перечисление" Тогда
        ИмяПоля = "Значение_Ссылка";
    ИначеЕсли Тип = "Справочник" Тогда
        ИмяПоля = "Значение_Ссылка";
    ИначеЕсли Тип = "Документ" Тогда
        ИмяПоля = "Значение_Ссылка";
    Иначе
        ИмяПоля = "Значение_"+Тип;
    КонецЕсли;
    Возврат "(SELECT "+ИмяПоля+" FROM ДополнительныеРеквизитыОбъектов Рекв (NoLock) WHERE Рекв.Объект = "+Выражение_идОбъект13+" AND Рекв.Имя = '"+Имя+"')";
КонецФункции

Функция тзп_Джойн(Алиас, Выражение_идОбъект13, Имя) Экспорт
    Возврат "LEFT JOIN ДополнительныеРеквизитыОбъектов "+Алиас+" (NoLock) ON "+Алиас+".Объект = "+Выражение_идОбъект13+" AND "+Алиас+".Имя = '"+Имя+"'";
КонецФункции
///******************************** ADirks 14.07.2016 ************

///******************************** ADirks 17.09.2012 ************
Функция Установить(Объект, Имя, Значение, Комментарий = "") Экспорт
    Значение_Имя = "";
    Значение_Значение = "";
    Тип = ТипЗначенияСтр(Значение);
    Если Тип = "Число" Тогда
        Значение_Имя = "Значение_Число";
        Значение_Значение = ""+Значение;
    ИначеЕсли Тип = "Строка" Тогда
        Значение_Имя = "Значение_Строка";
        Значение_Значение = "'"+Значение+"'";
    ИначеЕсли Тип = "Дата" Тогда
        Значение_Имя = "Значение_Дата";
        Значение_Значение = "'"+Формат(Значение, "ДГГГГММДД")+"'";
    ИначеЕсли Тип = "Документ" Тогда
        Значение_Имя = "Значение_Ссылка";
        Значение_Значение = "'"+РадугаСервис.ЗначениеВДлиннуюСтрокуБД(Значение)+"'";
        Тип = Тип+"."+Значение.Вид();
    ИначеЕсли Тип = "Справочник" Тогда
        Значение_Имя = "Значение_Ссылка";
        Значение_Значение = "'"+РадугаСервис.ЗначениеВДлиннуюСтрокуБД(Значение)+"'";
        Тип = Тип+"."+Значение.Вид();
    ИначеЕсли Тип = "Перечисление" Тогда
        Значение_Имя = "Значение_Ссылка";
        Значение_Значение = "'"+РадугаСервис.ЗначениеВДлиннуюСтрокуБД(Значение)+"'";
        Тип = Тип+"."+Значение.Вид();
    КонецЕсли;
    
    Коммент_Имя = "";
    Коммент_Знач = "";
    Если (Тип <> "Строка") И (ПустаяСтрока(Комментарий) = 0) Тогда
        Коммент_Имя = ", Значение_Строка";
        Коммент_Знач = ", '"+СокрП(Комментарий)+"'";
    КонецЕсли;
    
    Если ТипЗначения(Объект) = 2 Тогда
        идОбъект = Объект;
    Иначе
        идОбъект = РадугаСервис.ЗначениеВДлиннуюСтрокуБД(Объект);
    КонецЕсли;
    
    ТекстЗапроса = "Set NoCount ON
    |DELETE FROM ДополнительныеРеквизитыОбъектов
    |WHERE
    |    Объект = '"+идОбъект+"'
    |    AND Имя = '"+Имя+"'
    |
    |INSERT INTO ДополнительныеРеквизитыОбъектов
    |    (Объект, Имя, Тип, "+Значение_Имя+"  "+Коммент_Имя+")
    |VALUES
    |    ('"+идОбъект+"', '"+Имя+"', '"+Тип+"', "+Значение_Значение+"  "+Коммент_Знач+")
    |";
    Если ЗапросСКЛ.Выполнить(ТекстЗапроса) <> 1 Тогда
        Сообщить(ЗапросСКЛ.ПолучитьОписаниеОшибки(), "!");
        Возврат 0;
    КонецЕсли;
    Возврат 1;
КонецФункции
///******************************** ADirks 17.09.2012 ************

///******************************** ADirks 18.09.2012 ************
Функция Удалить(Объект, Имя) Экспорт
    ТекстЗапроса = "Set NoCount ON
    |DELETE FROM ДополнительныеРеквизитыОбъектов
    |WHERE
    |    Объект = :Объект~
    |    AND Имя = '"+Имя+"'
    |";
    ЗапросСКЛ.УстановитьТекстовыйПараметр("Объект", Объект);
    Если ЗапросСКЛ.Выполнить(ТекстЗапроса) <> 1 Тогда
        Сообщить(ЗапросСКЛ.ПолучитьОписаниеОшибки(), "!");
        Возврат 0;
    КонецЕсли;
    Возврат 1;
КонецФункции
///******************************** ADirks 18.09.2012 ************

///******************************** ADirks 30.08.2016 ************
Функция Константа(Имя) Экспорт
    Возврат Получить("const", Имя);
КонецФункции

Функция УстановитьКонстанту(Имя, Зн) Экспорт
    Возврат Установить("const", Имя, Зн);
КонецФункции
///******************************** ADirks 30.08.2016 ************

///******************************** ADirks 31.05.2013 ************
Функция тзЗначения(Объект, ИмяРекв, фКолонкаЗнач = 0) Экспорт
    ТекстЗапроса = "Set NoCount ON
    |SELECT
    |    Рекв.Имя,
    |    Рекв.Тип as Тип,
    |    Рекв.Значение_Ссылка,
    |    CASE Left(Рекв.Тип, 12) WHEN 'Перечисление' THEN Рекв.Значение_Ссылка ELSE $ПустойИД13 END as [Пр $Перечисление],
    |    CASE Left(Рекв.Тип, 10) WHEN 'Справочник' THEN Рекв.Значение_Ссылка ELSE $ПустойИД13 END as [Спр $Справочник],
    |    CASE Left(Рекв.Тип, 8)  WHEN 'Документ' THEN Рекв.Значение_Ссылка ELSE $ПустойИД13 END as [Док $Документ],
    |    Рекв.Значение_Число as Число,
    |    Рекв.Значение_Строка as Строка,
    |    Рекв.Значение_Дата as Дата
    |FROM
    |    ДополнительныеРеквизитыОбъектов Рекв (NoLock)
    |WHERE
    |    Рекв.Объект = :Объект~
    |";
    Если Найти(ИмяРекв, "%") = 0 Тогда
        ТекстЗапроса = ТекстЗапроса + "    AND Рекв.Имя = '"+ИмяРекв+"'";
    Иначе
        ТекстЗапроса = ТекстЗапроса + "    AND Рекв.Имя like '"+ИмяРекв+"'";
    КонецЕсли;
    
    //РадугаСервис.УстановитьТекстовыйПараметр("Объект", Объект);
    //Сообщить(РадугаСервис.ОбрМетаСКЛ(ТекстЗапроса));
    
    
    ЗапросСКЛ.УстановитьТекстовыйПараметр("Объект", Объект);
    тз = ЗапросСКЛ.ВыполнитьИнструкцию(ТекстЗапроса);
    
    Если фКолонкаЗнач = 1 Тогда
        тз.НоваяКолонка("Значение");
        тз.ВыбратьСтроки();
        Пока тз.ПолучитьСтроку() = 1 Цикл
            Тип = СтрокуВСписок(тз.Тип, ".", 1).ПолучитьЗначение(1);
            Если Тип = "Число" Тогда
                тз.Значение = тз.Число;
            ИначеЕсли Тип = "Строка" Тогда
                тз.Значение = тз.Строка;
            ИначеЕсли Тип = "Дата" Тогда
                тз.Значение = тз.Дата;
                
            Иначе
                тз.Значение = РадугаСервис.ЗначениеИзДлиннойСтрокиБД(Тип, тз.Значение_Ссылка);
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
    
    Возврат тз;
КонецФункции
///******************************** ADirks 31.05.2013 ************

///******************************** ADirks 09.07.2013 ************
Функция фЕстьЗначение(Объект, ИмяРекв) Экспорт
    тзп_Значения = "
    |SELECT *
    |FROM
    |    ДополнительныеРеквизитыОбъектов Рекв
    |WHERE
    |    Рекв.Объект = :Объект~
    |";
    Если Найти(ИмяРекв, "%") = 0 Тогда
        тзп_Значения = тзп_Значения + "    AND Рекв.Имя = '"+ИмяРекв+"'";
    Иначе
        тзп_Значения = тзп_Значения + "    AND Рекв.Имя like '"+ИмяРекв+"'";
    КонецЕсли;
    
    ТекстЗапроса = "Set NoCount ON
    |If Exists ("+тзп_Значения+")
    |    Select 1
    |Else
    |    Select 0
    |";
    
    ЗапросСКЛ.УстановитьТекстовыйПараметр("Объект", Объект);
    Возврат ЗапросСКЛ.ВыполнитьСкалярный(ТекстЗапроса);
КонецФункции
///******************************** ADirks 09.07.2013 ************

///******************************** ADirks 11.12.2014 ************
Функция тзОбъектыСоЗначением(ВидОбъекта, ИмяЗнач, Значение) Экспорт
    Значение_Имя = "";
    Значение_Значение = "";
    Тип = ТипЗначенияСтр(Значение);
    Если Тип = "Число" Тогда
        Значение_Имя = "Значение_Число";
        Значение_Значение = ""+Значение;
    ИначеЕсли Тип = "Строка" Тогда
        Значение_Имя = "Значение_Строка";
        Значение_Значение = "'"+Значение+"'";
    ИначеЕсли Тип = "Дата" Тогда
        Значение_Имя = "Значение_Дата";
        Значение_Значение = "'"+Формат(Значение, "ДГГГГММДД")+"'";
    ИначеЕсли Тип = "Документ" Тогда
        Значение_Имя = "Значение_Ссылка";
        Значение_Значение = "'"+РадугаСервис.ЗначениеВДлиннуюСтрокуБД(Значение)+"'";
        Тип = Тип+"."+Значение.Вид();
    ИначеЕсли Тип = "Справочник" Тогда
        Значение_Имя = "Значение_Ссылка";
        Значение_Значение = "'"+РадугаСервис.ЗначениеВДлиннуюСтрокуБД(Значение)+"'";
        Тип = Тип+"."+Значение.Вид();
    ИначеЕсли Тип = "Перечисление" Тогда
        Значение_Имя = "Значение_Ссылка";
        Значение_Значение = "'"+РадугаСервис.ЗначениеВДлиннуюСтрокуБД(Значение)+"'";
        Тип = Тип+"."+Значение.Идентификатор();
    КонецЕсли;

    ТекстЗапроса = "Set NoCount ON
    |SELECT
    |    Рекв.Объект [Объект $Справочник]
    |FROM
    |    ДополнительныеРеквизитыОбъектов Рекв
    |WHERE
    |    Left(Рекв.Объект, 4) = $ВидСправочника36."+ВидОбъекта+"
    |    AND Рекв.Имя = '"+ИмяЗнач+"'
    |    AND Рекв."+Значение_Имя+" = "+Значение_Значение+"
    |";
    тз = ЗапросСКЛ.ВыполнитьИнструкцию(ТекстЗапроса);
    Возврат тз;
КонецФункции
///******************************** ADirks 11.12.2014 ************

///******************************** ADirks 05.11.2015 ************
Функция тзИмена() Экспорт
    Возврат ЗапросСКЛ.ВыполнитьИнструкцию("Set NoCount ON
    |SELECT Distinct
    |    CASE WHEN Имя like 'Пл/Пор_%' THEN 'Пл/Пор_%' ELSE Имя END Имя
    |FROM
    |    ДополнительныеРеквизитыОбъектов
    |");
КонецФункции
///******************************** ADirks 05.11.2015 ************

//#else

///******************************** ADirks 13.11.2012 ************
Процедура тпДопРекв_Инит()
    тпДопРекв = СоздатьОбъект("ТТабличноеПоле.Запрос");
    тпДопРекв.Инит(Контекст, "тпДопРекв");
    тпДопРекв.ИмяНастройки = "ДопРеквОбъектов";
    тпДопРекв.НачальноеПредставление = 1;
    
    тпДопРекв.ДобавитьТаблицу("Рекв", "ДополнительныеРеквизитыОбъектов Рекв");
    
    тпДопРекв.ДобавитьКолонкуМета("идСтрока", "(Рекв.Объект + Рекв.Имя)", "Строка");
    тпДопРекв.КолонкиДанных("идСтрока");

    тпДопРекв.ДобавитьКолонкуМета("Объект", "Рекв.Объект", "Строка");
    тпДопРекв.ДобавитьКолонкуМета("Имя", "Рекв.Имя", "Строка");
    тпДопРекв.ДобавитьКолонкуМета("Тип", "Рекв.Тип", "Строка");
    тпДопРекв.ДобавитьКолонкуМета("Спр", "CASE Left(Рекв.Тип, 10) WHEN 'Справочник' THEN Рекв.Значение_Ссылка ELSE $ПустойИД13 END", "Справочник");
    тпДопРекв.ДобавитьКолонкуМета("Док", "CASE Left(Рекв.Тип, 8) WHEN 'Документ' THEN Рекв.Значение_Ссылка ELSE $ПустойИД13 END", "Документ");
    тпДопРекв.ДобавитьКолонкуМета("Число", "Рекв.Значение_Число", "Число");
    тпДопРекв.ДобавитьКолонкуМета("Строка", "Рекв.Значение_Строка", "Строка");
    тпДопРекв.ДобавитьКолонкуМета("Дата", "Рекв.Значение_Дата", "Дата");
    тпДопРекв.ДобавитьДату("Дата");
    
    тпДопРекв.ДобавитьСортировку("Порядок", "идСтрока");
    тпДопРекв.КлючСтроки("идСтрока");
    
    тпДопРекв.ДобавитьФильтр("_Имя_", "Строка", "Рекв.Имя");
    
    тпДопРекв.Показать();
КонецПроцедуры
///******************************** ADirks 13.11.2012 ************

Процедура тпДопРеквПриВыводеСтроки(Источник, ОформлениеСтроки, ДанныеСтроки, ТипРегиона)
    Кол = тпДопРекв.Колонки.Объект;
    Если Кол.Видимость = 1 Тогда
        Яч = ОформлениеСтроки.Ячейки.Объект;
        _Объект = РадугаСервис.ЗначениеИзДлиннойСтрокиБД("Справочник", ДанныеСтроки.Объект);
        Попытка
            Вид = _Объект.Вид();
        Исключение
            _Объект = РадугаСервис.ЗначениеИзДлиннойСтрокиБД("Документ", ДанныеСтроки.Объект);
            Попытка
                Вид = _Объект.Вид();
            Исключение
            КонецПопытки;
        КонецПопытки;
        Яч.Текст = ""+_Объект+"  ("+Вид+")";
    КонецЕсли;
КонецПроцедуры

///******************************** ADirks 05.11.2015 ************
// для формы
Функция тпДопРекв_Выбор(Источник, СтрТП, КолТП, ТипРегиона, ТипОбластиЯчейки) Экспорт
    идОбъект = Лев(СтрТП, 13);
    _Объект = РадугаСервис.ЗначениеИзДлиннойСтрокиБД("Справочник", идОбъект);
    Попытка
        Вид = _Объект.Вид();
    Исключение
        _Объект = РадугаСервис.ЗначениеИзДлиннойСтрокиБД("Документ", идОбъект);
        Вид = _Объект.Вид();
    КонецПопытки;
    
    ОткрытьФорму(_Объект);
    
    Возврат 1;
КонецФункции
///******************************** ADirks 05.11.2015 ************

///******************************** ADirks 13.11.2012 ************
// для формы
Процедура тпФлаги_Инит()
    тпФлаги = СоздатьОбъект("ТТабличноеПоле.Запрос");
    тпФлаги.Инит(Контекст, "тпФлаги");
    тпФлаги.ИмяНастройки = "ДопФлагиДокументов";
    
    тпФлаги.ДобавитьТаблицу("Флаги", "ФлагиДокументов Флаги (NoLock)");
    тпФлаги.ДобавитьТаблицу("жДок", "LEFT JOIN ЖурналДокументов жДок ON жДок.идДок9 = Флаги.идДок");

    тпФлаги.ДобавитьКолонкуМета("идСтрока", "(Флаги.идДок + Флаги.Имя)", "Строка",,, 0);
    тпФлаги.КолонкиДанных("идСтрока");
    тпФлаги.ДобавитьКолонкуМета("Док", "жДок.идДок13", "Документ");
    тпФлаги.ДобавитьКолонкуМета("Имя", "Флаги.Имя", "Строка");
    тпФлаги.ДобавитьКолонкуМета("Дата", "Флаги.ДатаУстановки", "Дата");
    тпФлаги.ДобавитьКолонкуМета("Значение", "Флаги.Значение", "Строка");
    
    тпФлаги.ДобавитьСортировку("Порядок", "идСтрока");
    тпФлаги.КлючСтроки("идСтрока");

    тпФлаги.Показать();
КонецПроцедуры
///******************************** ADirks 13.11.2012 ************

///******************************** ADirks 13.11.2012 ************
Процедура УстановитьФлаг()
    оДок = СоздатьОбъект("ТДокумент");
    оДок.УстановитьФлаг(ВыбДок, ВыбИмяФлага);
    тпФлаги.ОбновитьСтроки();
КонецПроцедуры

Процедура УдалитьФлаг()
    Ответ = Вопрос("Удалить "+тпФлаги.ТекущиеДанные.Док+": "+тпФлаги.ТекущиеДанные.Имя+"?", "Да+Нет");
    Если Ответ = "Да" Тогда
        оДок = СоздатьОбъект("ТДокумент");
        оДок.СброситьФлаг(тпФлаги.ТекущиеДанные.Док, тпФлаги.ТекущиеДанные.Имя);
        тпФлаги.ОбновитьСтроки();
    КонецЕсли;
КонецПроцедуры
///******************************** ADirks 13.11.2012 ************

//********************************************************//
Процедура ПриНачалеВыбораЗначения(Идентификатор, ФСО)
    Если Идентификатор = "ВыбИмяРекв" Тогда
        ФСО = 0;
        сзИмена = сзУникальныеЗначения(оДопРекв.тзИмена(), "Имя"); //:СписокЗначений
        сзИмена.Сортировать();
        нСтр = Длг.ВыбратьСтроку(сзИмена, "Имя доп.рекв.");
        Если нСтр > 0 Тогда
            ВыбИмяРекв = сзИмена.ПолучитьЗначение(нСтр);
        КонецЕсли;
        тпДопРекв.УстановитьФильтр("_Имя_", ВыбИмяРекв);
        тпДопРекв.ОбновитьТекстЗапроса();
    КонецЕсли;
КонецПроцедуры
//********************************************************//

///******************************** ADirks 24.04.2017 ************
Процедура ВыбИмяРекв_ИмяРекв()
    ВыбИмяРекв = ВыбИмяРекв;
    тпДопРекв.УстановитьФильтр("_Имя_", ВыбИмяРекв);
    тпДопРекв.ОбновитьТекстЗапроса();
КонецПроцедуры
///******************************** ADirks 24.04.2017 ************


///******************************** ADirks 13.11.2012
Процедура ПриВыбореЗакладки(Номер, Значение)
    Форма.ИспользоватьСлой(Значение, 2);
КонецПроцедуры
///******************************** ADirks 13.11.2012

///******************************** ADirks 13.11.2012 ************
Процедура ПриОткрытии()
    оПривязки = СоздатьОбъект("Общие.Форма.Привязки");
    оПривязки.Инит(Контекст);
    оПривязки.Добавить("тпДопРекв", "ПП", "Форма", "НН", "Форма");
    оПривязки.Добавить("тпФлаги", "ПП", "Форма", "НН", "Форма");

    Форма.ИспользоватьЗакладки(1);
    Форма.Закладки.ДобавитьЗначение("ДопРекв");
    Форма.Закладки.ДобавитьЗначение("Флаги");
    Форма.ИспользоватьСлой("ДопРекв", 2);
    
    оДопРекв = СоздатьОбъект("ТДополнительныеРеквизитыОбъектов");
КонецПроцедуры
///******************************** ADirks 13.11.2012 ************

Процедура ПослеСозданияФормы()
    Если ТипЗначенияСтр(Форма.Параметр) = "СписокЗначений" Тогда
        ВыбОбъект = Форма.Параметр.Получить("Объект");
    КонецЕсли;

    тпДопРекв_Инит();
    тпФлаги_Инит();
КонецПроцедуры


Процедура ПриЗакрытии()
КонецПроцедуры
///******************************** ADirks 08.10.2012 ************

//#endif
41 Сияющий Асинхраль
 
22.06.20
16:21
(33) Нет, идея неплоха, особенно, если учесть, что документы, которые соответствовали дополнительным табличным частям пихались год так на 1980, то бишь их тупо было не видно в журнале. Хотя вариант хранения все в одной ТЧ я тоже делал, он конечно гораздо красивее визуально, но сильно геморройнее в реализации (так у меня в семерке были документы мало того, что с несколькими табличными частями, так еще и и с папочками в таблчной части, которые открывались как папки в справочнике уровня так до третьего). НО, предложенный в (32) вариант Очень прост в исполнении и Очень надежен. Если надо, что сделать БЫСТРО, то лучше варианта нет...
42 vv036
 
22.06.20
16:35
(41) А нюансы с копированием документа. В том примере они не реализованы. Выгрузка через конвертацию, собери их, да ещё при ограничении по дате.
43 Сияющий Асинхраль
 
22.06.20
16:41
(42) А ты считаешь, что в выгрузке при помощи конвертации проще разделять табличные части, которые все понапиханы в одну табличную часть? Мне так было проще их собирать ТЧ в ТЧ. Копирование, кстати, там вполне, помнится, было нормально реализовано. Народ на указанном решении сидит уже лет 15 и еще долго будут сидеть потому что написать подобное на семерке надо еще лет десять :-(
44 Злопчинский
 
22.06.20
16:54
(43) Поддерживаю. я тоже за подчиненные доки.
45 vv036
 
22.06.20
17:25
(43) Нету там копирования подчиненых частей. 16 лет если быть точнее. Сидим. Но нюансы были, и много. Поэтому сейчас делать не стал бы. Во всяком случае в том варианте.
46 Сияющий Асинхраль
 
22.06.20
18:29
(45) Ну, может и дорабатывал, в чем проблема. Там доработки несколько строк, чтобы копировались ТЧ. Что скорее всего и делал. Или Вам нужно получить исключительно готовое решение без приложения собственных ручек? Ну так такого не бывает.
47 Сияющий Асинхраль
 
22.06.20
18:32
+(46) И да, ограничения по дате в КД обходятся не просто, а очень просто, конечно надо конвертацию знать... Но куда же сейчас без нее...
48 Сияющий Асинхраль
 
22.06.20
18:37
На самом деле, когда видел, и даже покупал (денюшки потратил :-)) решение для организации нескольких ТЧ, когда при переходе между разными страницами документа казалось, что реально переходится между разными табличными частями. Поглядел тогда на то решение, подивился, да внедрять не стал. То решение чуток калечило основное правило работы с документами, которое частенько игнорять в семерке, да видел, что и в восьмерке не очень за этим следят, а именно, документ, при открытии не должен меняться. Т.е. если некто открыл документ, не менял его и сразу закрыл, этот документ не должен задавать вопрос на сохранение...
49 Salimbek
 
22.06.20
19:25
Присоединяюсь к (40) хранить в отдельной таблице. Я так и делал у себя во времена 7.7
Дело в том, что бизнес развивается и ему нужно постоянно что-то допиливать, а реструктуризация базы у нас занимала очень много времени. Поэтому доработки делались при помощи ТурбоМД, а для хранения данных - такая вот таблица. (Вообще-то была и еще одна таблица, специфическая, для хранения данных типа "Регистр Сведений" с очень большим объемом информации).

Например, стандартный документ "Рекламная Акция" от разработчиков - подразумевал один документ или на конкретный магазин, или сразу на всю сеть (если поле Подразделение не заполнено). Но нам надо было делать акции и по регионам, и выборочно, по какому-то признаку. Поэтому начал хранить в такой вот Таблице информацию. Кодом ее вытаскивал на Форму, рисовал галочки. При записи - укладывал обратно. Для обмена - анализировал и выгружал Документ туда, куда надо.
50 tgu82
 
22.06.20
19:30
(49) А я имея в путевых листах в моей самописной чатси бухии 7.7 (с регистрами ОУ и т.д.) несколько табличных частей, делал через строки неограниченной длины в документе и брал на себя контроль целостности. ЛЕт 10 проработало без проблем уже и когда я оттуда ушел
51 Franchiser
 
гуру
22.06.20
21:06
Задача отменяется пока, всем спасибо
52 Злопчинский
 
22.06.20
21:07
(51) аллилуйя!
53 Cthulhu
 
22.06.20
21:34
(41): как опробовавший все три варианта - не надо выдумывать, пжалст.
за любой год - журнал засирается (выборки, которые без интервалов - например, подчиненных - тоже).
и - нет, нихрена композитная тч не "сильно геморройнее" в реализации (а совсем наоборот - гораздо проще. с кодом, использующим метаданных - и вовсе копипаста на все времена).
54 Сияющий Асинхраль
 
22.06.20
21:44
(53) Я тоже испробовал ВСЕ три варианта, еще раз повторю, вариант с одной ТЧ сильно геморройнее, плюс, гораздо проще нарваться на ограничение по количеству строк в ТЧ (у меня было такое, в результате чего пришлось полностью переписывать уже имеющиеся документы). Еще раз, у меня были и документы, где в одной ТЧ хранилось по пять-шесть табличных частей, да, они работали достаточно устойчиво, но количество кода, которые они требовали очень напоминало сегодняшние документы восьмерки - тысячи три-четыре строчек, а иногда и больше. Хотя да, все замечательно и красиво, вот только мало кто эти документики переделывать после меня мог, и не потому что я писал криво, совсем нет...
55 Cthulhu
 
22.06.20
22:43
(54): извините, но вы несете бред. нет, не легко - нужно постараться. ещё раз, лишние документы - зло. отсутстие полнофункциональной корректировки тч - зло. пляски вокруг стандартно реализованного функционала 1с - зло (копирование документа, пометка на удаление, удаление помеченных, и т.п.). и геморроя в композитной тч - намного меньше (только форма, причем код размножаемый копипастой, а и колонки тч рисуются стандартно в пофигураторе).
и - извините, ваше упрямство при явной неправоте - делают общение с вами уныло скучным. удачи.
56 Сияющий Асинхраль
 
22.06.20
22:46
(55) Удачи. Каждый остался при своем мнении. Но, кстати, если Вы не в состоянии написать пару строчек, чтобы копировались дополнительные ТЧ, то, тут действительно говорить не о чем...
57 zladenuw
 
22.06.20
23:44
Где то видел конфу. Где один справочник содержит кучу типов через отбор работал. Прикольно. Но они потом ушли от 1с. То и так тут же можно но вопрос имён объектов и все остальное лучше уже табличная часть. В шапке только статистические реквизиты. Остальное в тч. Как то так. И так же можно динамические табличный части сделать
58 victuan1
 
23.06.20
06:57
(44) А я за подчиненные справочники ;)

Вообще, я использовал разные способы хранения доп. ТЧ (и до сих пор использую всё это многообразие, разные способы применимы для разных задач):

1) Доп. ТЧ хранить в шапке основного дока в реквизите "Строка не огранич. длины", пакую в нее ТЗ через ф-ию ЗначениеВСтрокуВнутр.
Ограничение: лучше использовать только для маленьких ТЧ, реквизиты которые НЕ ссылочные данные (чтобы не нарушать ссылочную целостность при удалении помеченных), например Таблица серийных номеров.
2) композитная ТЧ (как у Ктулху) - когда строк в ТЧ не много (чтобы суммарно не достичь ограничения в 9999 строк); колонки этих ТЧ подобны или взаимозаменимы, чтобы не было пустот (дыр) при хранении в БД.
3) Вторая ТЧ в доп. документе - использую если нужно каждую ТЧ проводить отдельно по своему алгоритму, например в штатной ТЧ - проводим выпуск продукции, а в доп.ТЧ (служебный документ) - проводим списание сырья для этой продукции
4) Вторая ТЧ в служебном справочнике - использую когда много строк в ТЧ и для всех прочих задач - наиболее универсальный вариант.
59 Salimbek
 
23.06.20
19:22
(58) А допТЧ в виде чистой SQL-таблицы с нужными полями и индексами не пробовал? :-)
60 Djelf
 
23.06.20
19:42
(59) Решения у victuan1 универсальны, они не завязаны на sql.
Дальше делай выводы сам.
61 Salimbek
 
23.06.20
19:46
(60) Да все я понимаю ))) Подкалываю просто.
62 victuan1
 
24.06.20
19:17
(59) Ну вот хочу освоить 5-ый вариант - хранить во внешней БД.
SQL-таблицы - не знаю - не универсально. Нужно выбрать что-то бесплатное, что будет работать у всех.
63 Cthulhu
 
24.06.20
19:41
(62): sqlite
64 tgu82
 
24.06.20
22:11
(62) Для контроля целостности лучше все-таки в справочнике хранить мне кажется. Хотя вот я делал -по-сути каждая из 3-х тч - делала проведение по своему регистру. Вот и хранить в-принципе можно просто в регистрах, запретив их автоочистку.
65 victuan1
 
26.06.20
07:59
(64) Да, такой подход видел в конфигурации "Астор: Торговый дом"