GUID в 1С 8.3 - как с ними быть

12.02.24

Разработка - Универсальные функции

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

1. Как получить GUID какой-то ссылки в коде.

ГУИД = Ссылка.УникальныйИдентификатор();
ГУИДСтрокой = СокрЛП(ГУИД);

В комментариях подсказали, как строкой проще получить:

ГУИДСтрокой = XMLСтрока(Ссылка);

2. Как получить ссылку, имея строку GUID, и зная, что это такое.

Если ТипЗнч(ГУИД) = Тип("Строка") Тогда
	ГУИД = новый УникальныйИдентификатор(ГУИД);
Иначе
	ГУИД = ГУИД;
КонецЕсли;
Ссылка = Справочники[ВидСправочника].ПолучитьСсылку(ГУИД);
Ссылка = Документ[ВидДокумента].ПолучитьСсылку(ГУИД);
// ну и т.д. ПланыВидовХарактеристик, ПланыОбмена ....

 

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

Тут есть прекрасный момент, он заключается в том, что вам в любом случае вернется ссылка указанного вида справочника (документа, плана и etc), и ЗначениеЗаполнено() для нее вернет вам Истину (тада-а-ам). Поэтому, можно только проверить, не ли в текстовом представлении слов "<Объект не найден>".

Если Найти(СокрЛП(Ссылка), "<Объект не найден>") > 0 Тогда
	//__ это не ссылка
	Ссылка = Неопределено; // ну, или Справочник[ВидСправочника].ПустаяСсылка();
Иначе
	//__ ура, это наша ссылка
КонецЕсли;

(Добавлено позже) Опять же, подсказали в комментариях.

Если вы пишите в рамках стандартной конфигурации, то можно воспользоваться функцией:

ОбщегоНазначения.СсылкаСуществует();

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

Функция СсылкаСуществует(ЛюбаяСсылка, ИмяТаблицы=Неопределено) Экспорт
    УстановитьПривилегированныйРежим(Истина);
    ТекстЗапроса = "
        |ВЫБРАТЬ
        |    Ссылка
        |ИЗ
        |    [ИмяТаблицы]
        |ГДЕ
        |    Ссылка = &Ссылка
        |";
    Если ИмяТаблицы = Неопределено Тогда 
        ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "[ИмяТаблицы]", ИмяТаблицыПоСсылке(ЛюбаяСсылка));
    Иначе
        ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "[ИмяТаблицы]", ИмяТаблицы);
    КонецЕсли;    
    
    Запрос = Новый Запрос;
    Запрос.Текст = ТекстЗапроса;
    Запрос.УстановитьПараметр("Ссылка", ЛюбаяСсылка);
    
    Возврат НЕ Запрос.Выполнить().Пустой();
КонецФункции

Функция ИмяТаблицыПоСсылке(Ссылка) Экспорт
    Возврат Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)).ПолноеИмя();
КонецФункции

4. Как получить ссылку, не зная, что это за ГУИД.

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

Функция НайтиСсылкуЛюбогоТипаПоГУИД(Знач ГУИД)
	//__ пусть ГУИД у нас или строка, или уже УникальныйИдентификатор
	Если ТипЗнч(ГУИД) = Тип("Строка") Тогда
		ГУИД = новый УникальныйИдентификатор(ГУИД);
	Иначе
		ГУИД = ГУИД;
	КонецЕсли;
	Ссылка = Неопределено;
	Для Каждого Мета из Метаданные.Справочники Цикл
		Ссылка = Справочники[Мета.Имя].ПолучитьСсылку(ГУИД);
		//___ хотелось бы, но нет, эта ### возвращает <Объект не найден> и ЗначениеЗаполнено() - Истина
		//	Если ЗначениеЗаполнено(Ссылка) Тогда
		//		Возврат Ссылка;
		//	КонецЕсли;
		//___ посему, проверка будет извратной
		Если Найти(СокрЛП(Ссылка), "<Объект не найден>") > 0 Тогда
			Ссылка = Неопределено;
		Иначе
			Возврат Ссылка;
		КонецЕсли;
	КонецЦикла;
	// и далее то же самое для Метаданные. ->
	// Документы, ПланыВидовХарактеристик, ПланыСчетов, ПланыВидовРасчета, БизнесПроцессы, Задачи, ПланыОбмена
	// для документов еще приведу, остальное - на "домашнее задание" ))
	Для Каждого Мета из Метаданные.Документы Цикл
		Ссылка = Документы[Мета.Имя].ПолучитьСсылку(ГУИД);
		Если Найти(СокрЛП(Ссылка), "<Объект не найден>") > 0 Тогда
			Ссылка = Неопределено;
		Иначе
			Возврат Ссылка;
		КонецЕсли;
	КонецЦикла;
	// ...
	Возврат Ссылка;
КонецФункции

 

5. Как получить Ссылки ГУИД в запросе.

Запрос = новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ 
|  Справочник.Ссылка КАК Ссылка,
|  УНИКАЛЬНЫЙИДЕНТИФИКАТОР(Справочник.Ссылка) КАК ГУИД,
|  ПРЕДСТАВЛЕНИЕ(УНИКАЛЬНЫЙИДЕНТИФИКАТОР(Справочник.Ссылка)) КАК ГУИДСтрокой
|ИЗ Справочники._НекийСправочник_ КАК Справочник
|";

Важно! Тут есть 2 замечания:

а) Это работает только с релиза 8.3.22.

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

 

6. Получение строки GUID из битой ссылки.

Имеется в виду, когда у вас где-то появляется надпись типа "<Объект не найден> (54:b3c200155d0a3b0111ed71bc04838993)", а надо получить, собственно строку GUID типа "04838993-71bc-11ed-b3c2-00155d0a3b01".

Функция ГУИДСтрИзОбъектНеНайден(ГУИДОбъекта)
	//ГУИДУдОбъекта - это строка, возвращаемая из битой ссылки вида
	//"<Объект не найден> (54:b3c200155d0a3b0111ed71bc04838993)"
	ГУИДОбъектаСтр = СтрЗаменить(ГУИДОбъекта,"<Объект не найден> (","");
	ГУИДОбъектаСтр = СтрЗаменить(ГУИДОбъектаСтр,")","");
	ГУИДОбъектаСтр = СтрЗаменить(ГУИДОбъектаСтр,"0x","");
	ГУИДОбъектаСтр = Сред(ГУИДОбъектаСтр, Найти(ГУИДОбъектаСтр,":")+1, СтрДлина(ГУИДОбъектаСтр));
	// Преобразуем GUID
	ГУИД = Сред(ГУИДОбъектаСтр,25,8)+
		"-"+Сред(ГУИДОбъектаСтр,21,4)+"-"+Сред(ГУИДОбъектаСтр,17,4)+
			"-"+Сред(ГУИДОбъектаСтр,1,4)+"-"+Сред(ГУИДОбъектаСтр,5,12);
	//и получаем ГУИД 04838993-71bc-11ed-b3c2-00155d0a3b01
	Возврат ГУИД;
КонецФункции

 

GUID

См. также

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

21.05.2024    16628    dimanich70    81    

134

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    3795    3    John_d    11    

57

Универсальные функции Программист Платформа 1С v8.3 Бесплатно (free)

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

30.11.2023    5199    ke.92@mail.ru    16    

65

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    13419    YA_418728146    7    

165

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    3254    52    progmaster    8    

4

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    18010    160    sapervodichka    112    

134

Универсальные функции Механизмы типовых конфигураций БСП (Библиотека стандартных подсистем) Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    8137    quazare    8    

110
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. alexsy 12.02.24 08:25 Сейчас в теме
1. можно короче: XMLСтрока(Ссылка)
DrAku1a; DrZombi; EvgeniyOlxovskiy; atdonya; glek; ImHunter; +6 Ответить
2. ImHunter 327 12.02.24 08:30 Сейчас в теме
Ну... Для тех, кто в теме, Омерик не открыто.
Основное замечание - перебор с использованием СокрЛП(...).
5. atdonya 107 12.02.24 09:23 Сейчас в теме
(2)СокрЛП(...) - это привычка из 7-ки осталась. Там строки заданной длины периодически без объявления войны возвращают в конце пробелы. )))
10. CheBurator 2696 12.02.24 13:52 Сейчас в теме
(5) хз, что там у автора без объявления войны, в 77 вроде все нормально строки всегда возвращались - там где заявлено/ожидается без пробелов - возвращается без пробелов, там где заявлено/ожидается с пробелами - возвращается с пробелами.
.
Единственное место где есть особенность - возвращение Спр.Наименование. Здесь результат возвращается без хвостовых пробелов.
.
Было бы интересно где у автора наблюдались глюки.
18. atdonya 107 12.02.24 16:36 Сейчас в теме
(10)я нарывался в разных местах. Навскидку, помню, что если в таблице значений указан размер строки, то при обращении он возвращает с хвостовыми пробелами.
21. CheBurator 2696 12.02.24 16:53 Сейчас в теме
(18) Да, именно так, что тут нелогичного?
Если колонка в ТЗ типизирована как строка без указания длины, то какую строку запихнуть - такая длина и будет
.
//*******************************************
Процедура Сформировать()
	
	ТЗ = СоздатьОбъект("ТаблицаЗначений");
	ТЗ.НоваяКолонка("Строка","Строка");
		ТЗ.НоваяСтрока(); ТЗ.Строка = "12345     "; // тут 5 пробелов в хвосте
		ТЗ.НоваяСтрока(); ТЗ.Строка = "67890";
	
	Предупреждение(""+
		СтрДлина(ТЗ.ПолучитьЗначение(1,"Строка"))+","+
		СтрДлина(ТЗ.ПолучитьЗначение(2,"Строка")));

КонецПроцедуры
.
длина в первой строке - 10, длина во второй строке - 5.
.
если выбирать строковые реквизиты запросом - строковое значение реквизита (без разницы с хвостовыми пробелами или нет) будет такой длины, как указано в конфигураторе.
.
как бы в целом все логично.
.
если типизируем пример выше СТРОГО - то и получим строго
.

	ТЗ = СоздатьОбъект("ТаблицаЗначений");
	ТЗ.НоваяКолонка("Строка","Строка");
		ТЗ.НоваяСтрока(); ТЗ.Строка = "12345     "; // тут 5 пробелов в хвосте
		ТЗ.НоваяСтрока(); ТЗ.Строка = "67890";
	
	Предупреждение("до "+
		СтрДлина(ТЗ.ПолучитьЗначение(1,"Строка"))+","+
		СтрДлина(ТЗ.ПолучитьЗначение(2,"Строка")));

	ТЗ.УстановитьПараметрыКолонки("Строка","Строка",15);		
	
	Предупреждение("после  "+
		СтрДлина(ТЗ.ПолучитьЗначение(1,"Строка"))+","+
		СтрДлина(ТЗ.ПолучитьЗначение(2,"Строка")));
Показать


до: 10,5
после: 15,15
.
когда источник строки неизвестен и ожидается без хвостовых пробелов - тоже юзаю СокрЛП ;-)
3. headMade 144 12.02.24 09:07 Сейчас в теме
п.п.3 см ОбщегоНазначения.СсылкаСуществует()
Orlando Skibraves; EvgeniyOlxovskiy; atdonya; +3 Ответить
4. atdonya 107 12.02.24 09:15 Сейчас в теме
(3)
спасибо за подсказку, я не нашел сам, когда искал.
6. basicmaster 2 12.02.24 10:16 Сейчас в теме
п1. XMLСтрока - жжет однозначно, а еще позволяет получить Идентификатор (т.е. Значение) перечисления так, как оно указано в конфигураторе!

п2. вместо Справочники[ВидСправочника].ПолучитьСсылку(ГУИД)
можно более универсально при помощи функциональной формы оператора Новый:
Возврат Вычислить( СтрШаблон( "Новый %1Ссылка.%2(Новый УникальныйИдентификатор(""%3""))" ,ТипОбъекта,ВидОбъекта,ГУИДОбъекта) );
- это позволит избежать условного ветвления по вариантам Справочники, Документы, ПВХ ...

п3. еще вариант ПустаяСтрока(Ссылка.ВерсияДанных)
- а вообще по поводу более "правильного" и/или "производительного" способа проверки битых ссылок споры на просторах ведутся издревле еще с 8.0.

п4. а тут лучше предусмотреть возврат не одиночного значения, а массива, т.к. платформа не гарантирует уникальность ГУИД в пределах ИБ (уникальность гарантируется только в пределах таблицы). при традиционном вводе данных в ИБ платформа лишь старается выдавать уникальные ид-шники. но абсолютно не помешает Вам при обмене загрузить один ГУИД из базы источника в несколько объектов целевой ИБ.

п5. судя по последним тенденциям при выпуске новых релизов Бух и ЗУП - скоро мы и в ЕРП доживем до конфигурации работающей без режима совместимости - так что можно уже потихоньку брать метод в оборот... тем более что вроде как есть "честный метод обхода" режима совместимости без снятия с поддержки, смс и регистрации.

п6. видимо Ваша функция специально нужна для получения ГУИД зная только представление битой ссылки ?
ведь программно можно обойтись более традиционными методами
Справочники.Валюты.ПолучитьСсылку(Новый УникальныйИдентификатор("7602b761-2f0f-430d-9bee-58bdc0c95e27")).УникальныйИдентификатор()
или
XMLСтрока(Справочники.Валюты.ПолучитьСсылку(Новый УникальныйИдентификатор("7602b761-2f0f-430d-9bee-58bdc0c95e27")))
mikeA; ixijixi; alexsy; +3 Ответить
7. dsdred 3526 12.02.24 10:59 Сейчас в теме
А можно было и не мучится
https://infostart.ru/1c/articles/1788844/
artbear; JohnyDeath; atdonya; EvgeniyOlxovskiy; +4 Ответить
20. atdonya 107 12.02.24 16:42 Сейчас в теме
(7)спасибо, наткнись я раньше, сэкономил бы время ))
8. SerVer1C 794 12.02.24 11:24 Сейчас в теме
4. Как получить ссылку, не зная, что это за ГУИД.

Перебирать все метаданные НЕ надо !!! (3 восклицательных знака)
Стреляем ГУИДом в любой ссылочный тип - если попали, то норм, если нет, то нам выдаст ссыль <Объект не найден>. В этой ссыли мы видим искомый тип. Идём в него и получаем ссылку.
11. xnd 94 12.02.24 13:56 Сейчас в теме
(8) Не вводите людей в заблуждение - в "объект не найден" будет тип которым стреляли :)
12. SerVer1C 794 12.02.24 13:57 Сейчас в теме
(11) Читайте внимательнее:
если нет, то нам выдаст ссыль <Объект не найден>. В этой ссыли мы видим искомый тип.
13. xnd 94 12.02.24 14:02 Сейчас в теме
(12) вот пример - когда гуидом организации стрельнул в номенклатуру и партнера

Ссылки отличаются типом в начале (который внезапно не организация)
Прикрепленные файлы:
14. SerVer1C 794 12.02.24 14:04 Сейчас в теме
(13) Так я про это и пишу. У нас же изначально есть только гуид, а там типа нет. Вот для этого нам сначала надо обратиться, например, к любому справочнику, только после этого у нас будет ссылка, из которой достаем тип.
15. xnd 94 12.02.24 14:06 Сейчас в теме
(14) ну я же привел пример когда я два раза стрельнул мимо и в "объекте не найден" разные типы ( оба неверные)
16. SerVer1C 794 12.02.24 14:32 Сейчас в теме
(15) Согласен, напутал. Тип в ссылке всегда будет тот, который запрашиваем. Значит без перебора всех метаданных не обойтись.
17. atdonya 107 12.02.24 16:32 Сейчас в теме
(8)не совсем, он выдаст "Объект не найден" для того вида справочника/документа, что мы запросили, в том и прикол.
9. dsdred 3526 12.02.24 11:41 Сейчас в теме
3. Как проверить, есть ли такая ссылка, при подобном получении.


это вредный совет. Видимо не попадались восстановленные ссылки.
Некоторые восстанавливают ссылки и в наименование загоняют "<Объект не найден> (54:b3c200155d0a3b0111ed71bc04838993)"


// Проверяет физическое наличие записи в информационной базе данных о переданном значении ссылки
//
// Параметры:
//  ЛюбаяСсылка - значение любой ссылки информационной базы данных
// 
// Возвращаемое значение:
//  Истина - ссылка физически существует;
//  Ложь   - ссылка физически не существует
//
Функция СсылкаСуществует(ЛюбаяСсылка, ИмяТаблицы=Неопределено) Экспорт
    УстановитьПривилегированныйРежим(Истина);
    ТекстЗапроса = "
        |ВЫБРАТЬ
        |    Ссылка
        |ИЗ
        |    [ИмяТаблицы]
        |ГДЕ
        |    Ссылка = &Ссылка
        |";
    Если ИмяТаблицы = Неопределено Тогда 
    	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "[ИмяТаблицы]", ИмяТаблицыПоСсылке(ЛюбаяСсылка));
	Иначе
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "[ИмяТаблицы]", ИмяТаблицы);
	КонецЕсли;	
	
    Запрос = Новый Запрос;
    Запрос.Текст = ТекстЗапроса;
    Запрос.УстановитьПараметр("Ссылка", ЛюбаяСсылка);
    
    Возврат НЕ Запрос.Выполнить().Пустой();
    
КонецФункции

// Возвращает полное имя объекта метаданных по переданному значению ссылки
// Например,
//  "Справочник.Номенклатура";
//  "Документ.ПриходнаяНакладная"
//
// Параметры:
//  Ссылка - ЛюбаяСсылка - значение ссылки, для которого необходимо получить имя таблицы ИБ
// 
// Возвращаемое значение:
//  Строка - полное имя объекта метаданных для указанного значения ссылки
//
Функция ИмяТаблицыПоСсылке(Ссылка) Экспорт
    
    Возврат Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)).ПолноеИмя();
    
КонецФункции

Показать



5. Как получить Ссылки ГУИД в запросе.
а) Это работает только с релиза 8.3.22.

Не совсем так. Могу ошибаться но по-моему работает на релизах вышедших после релиза 8.3.22.
Плюсом, так же работает в режимах совместимости:
Я попробовал режим совместимости «Версия 8.3.1». Работает.
Тогда я включил режим совместимости «Версия 8.2.13». Работает.
19. atdonya 107 12.02.24 16:40 Сейчас в теме
(9)да, про "ОбщегоНазначения.СсылкаСуществует()" уже выше написали, я такой метод не нашел тогда, потом посмотрел, как это реализовано. Вас тоже благодарю.
Про релиз - официально они объявили это с 22-го, ставить более ранние, чтобы проверить такую мелочь не хочется.
Насчет режима совместимости не знаю, возможно дело в том, что это в запросах, а не в самом коде, а там что-то не проверяется.
22. Ferth 19.02.24 13:06 Сейчас в теме
Не знала, что можно получить гуид в запросе, как-то новость прошла мимо меня. В последнее время часто приходилось с этим сталкиваться, использовала отдельную обработку( В консоли, конечно, было бы удобней
23. Lex_Liven 03.10.24 09:55 Сейчас в теме
Нате вам еще один вариант исполнения п.3

Если Ссылка.ПолучитьОбъект()<>Неопределено Тогда

Специально проверил, все перечисленные методы дают абсолютно одинаковую производительность.
Если что, я сравнил 4 метода, один из них в двух вариантах - с именем таблицы и без нее:
	Если Ссылка.ПолучитьОбъект()=Неопределено Тогда
		Рез = Рез + 1;
	КонецЕсли;

	Если СсылкаСуществует(Ссылка, "Справочник.Марки") Тогда
		Рез = Рез + 1;
	КонецЕсли;
	
	Если СсылкаСуществует(Ссылка) Тогда
		Рез = Рез + 1;
	КонецЕсли;
	
	Если ПустаяСтрока(Ссылка.ВерсияДанных) Тогда
		Рез = Рез + 1;
	КонецЕсли;
		
	Если Найти(СокрЛП(Ссылка), "<Объект не найден>") > 0 Тогда
		Рез = Рез + 1;
	КонецЕсли;
Показать
Оставьте свое сообщение