├── README.md └── ИнтерфейсДляПрограммногоИзмененияФорм.bsl /README.md: -------------------------------------------------------------------------------- 1 | Простой способ программного создания новых элементов, команд и реквизитов на форме. 2 | Также здесь реализованы те действия, которая платформа выполняет при интерактивной работе с формой (создание заголовоков по имени, автоматическое именование элементов, автоматическое определение типа поля, в зависимости от типа реквизита и др.). 3 | 4 | Подробнее: https://infostart.ru/1c/articles/1556681 5 | -------------------------------------------------------------------------------- /ИнтерфейсДляПрограммногоИзмененияФорм.bsl: -------------------------------------------------------------------------------- 1 | // см. МодификацияКонфигурацииПереопределяемый.ПриСозданииНаСервере 2 | // 3 | Процедура ПриСозданииНаСервере(Форма, Отказ, СтандартнаяОбработка) Экспорт 4 | 5 | Результат = префикс_КлиентСервер.ПолучитьСтруктурированноеОписаниеИмениФормы(Форма.ИмяФормы); 6 | ВидМетаданных = Результат.ВидМетаданных; 7 | ТипОбъекта = Результат.ТипОбъекта; 8 | ИмяФормы = Результат.ИмяФормы; 9 | 10 | Если ТипОбъекта = "ЗаказКлиента" Тогда 11 | Если ИмяФормы = "ФормаДокумента" Тогда 12 | ДобавитьРеквизитСпецификацияИКомандуПоФормированиюПроизводственныхДокументов(Форма); 13 | КонецЕсли; 14 | ИначеЕсли ТипОбъекта = "Номенклатура" Тогда 15 | Если ИмяФормы = "ФормаЭлемента" Тогда 16 | ДобавитьНовыеРеквизитыВКарточкуНоменклатуры(Форма); 17 | КонецЕсли; 18 | ИначеЕсли ИмяФормы = "ФормаОтчета" ИЛИ ВидМетаданных = "Отчет" Тогда 19 | ЗапомнитьИмяОтчетаВРеквизитИзПараметра(Форма); 20 | КонецЕсли; 21 | 22 | КонецПроцедуры 23 | 24 | #Область ДоработкаФорм_ВнешнийПрограммныйИнтерфейс 25 | 26 | // Функция добавляет реквизит формы 27 | // 28 | // Параметры: 29 | // Форма - ФормаКлиентскогоПриложения 30 | // Имя - Строка, содержит имя реквизита 31 | // Тип - Строка типа, Тип или ОписаниеТипов 32 | // Заголовок - Строка, содержит отображаемый текст реквизита 33 | //Если заголовок не задан, то формируется функцией "ПолучитьЗаголовокПоИмени" 34 | // Путь - Строка, содержит путь к реквизиту, не включая имя реквизита 35 | // СохраняемыеДанные - Булево, если Истина - указывает, что это сохраняемый при записи реквизит, по умолчанию Ложь 36 | // Значение - Произвольный, значение, присваиваемое реквизиту после его создания 37 | // 38 | // Возвращаемое значение: 39 | // РеквизитФормы - созданный реквизит формы 40 | // 41 | Функция ДобавитьРеквизит(Форма, Имя, Тип, Заголовок = Неопределено, Путь = Неопределено, СохраняемыеДанные = Неопределено, Значение = Неопределено) 42 | 43 | СвойстваРеквизита = Новый Структура; 44 | СвойстваРеквизита.Вставить("Имя", Имя); 45 | СвойстваРеквизита.Вставить("Тип", Тип); 46 | СвойстваРеквизита.Вставить("Заголовок", Заголовок); 47 | СвойстваРеквизита.Вставить("Путь", Путь); 48 | СвойстваРеквизита.Вставить("СохраняемыеДанные", СохраняемыеДанные); 49 | СвойстваРеквизита.Вставить("Значение", Значение); 50 | СвойстваРеквизитов = Новый Массив; 51 | СвойстваРеквизитов.Добавить(СвойстваРеквизита); 52 | Возврат ДобавитьРеквизиты(Форма, СвойстваРеквизитов)[0]; 53 | 54 | КонецФункции 55 | 56 | // Функция добавляет реквизиты формы 57 | // 58 | // Параметры: 59 | // Форма - ФормаКлиентскогоПриложения 60 | // СвойстваРеквизитов - Массив структур: 61 | // * Имя - Строка, содержит имя реквизита 62 | // * Тип - Строка типа, Тип или ОписаниеТипов 63 | // * Заголовок - необязательный элемент, Строка, содержит отображаемый текст реквизита 64 | //Если заголовок не задан, то формируется функцией "ПолучитьЗаголовокПоИмени" 65 | // * Путь - необязательный элемент, Строка, содержит путь к реквизиту, не включая имя реквизита 66 | // * СохраняемыеДанные - необязательный элемент, Булево, если Истина - указывает, что это сохраняемый при записи реквизит, по умолчанию Ложь 67 | // * Значение - необязательный элемент, Произвольный, значение, присваиваемое реквизиту после его создания 68 | // 69 | // Возвращаемое значение: 70 | // Массив Реквизитов формы - созданные реквизиты формы 71 | // 72 | Функция ДобавитьРеквизиты(Форма, СвойстваРеквизитов) 73 | 74 | НовыеРеквизиты = Новый Массив; 75 | 76 | Для Каждого СвойстваРеквизита Из СвойстваРеквизитов Цикл 77 | 78 | Имя = СвойстваРеквизита.Имя; 79 | Тип = СвойстваРеквизита.Тип; 80 | Если ТипЗнч(Тип) = Тип("Строка") Тогда 81 | Тип = Новый ОписаниеТипов(Тип); 82 | ИначеЕсли ТипЗнч(Тип) = Тип("Тип") Тогда 83 | МассивТипов = Новый Массив; 84 | МассивТипов.Добавить(Тип); 85 | Тип = Новый ОписаниеТипов(МассивТипов); 86 | КонецЕсли; 87 | Путь = Неопределено; Заголовок = Неопределено; СохраняемыеДанные = Неопределено; 88 | СвойстваРеквизита.Свойство("Путь", Путь); 89 | СвойстваРеквизита.Свойство("Заголовок", Заголовок); 90 | СвойстваРеквизита.Свойство("СохраняемыеДанные", СохраняемыеДанные); 91 | Если Путь = Неопределено Тогда 92 | Путь = ""; 93 | КонецЕсли; 94 | Если Заголовок = Неопределено Тогда 95 | Заголовок = ПолучитьЗаголовокПоИмени(Имя); 96 | КонецЕсли; 97 | Если СохраняемыеДанные = Неопределено Тогда 98 | СохраняемыеДанные = Ложь; 99 | КонецЕсли; 100 | 101 | НовыйРеквизит = Новый РеквизитФормы(Имя, Тип, Путь, Заголовок, СохраняемыеДанные); 102 | НовыеРеквизиты.Добавить(НовыйРеквизит); 103 | 104 | КонецЦикла; 105 | 106 | Форма.ИзменитьРеквизиты(НовыеРеквизиты); 107 | 108 | Для Каждого СвойстваРеквизита Из СвойстваРеквизитов Цикл 109 | Если СвойстваРеквизита.Свойство("Значение") И СвойстваРеквизита.Значение <> Неопределено Тогда 110 | Форма[СвойстваРеквизита.Имя] = СвойстваРеквизита.Значение; 111 | КонецЕсли; 112 | КонецЦикла; 113 | 114 | Возврат НовыеРеквизиты; 115 | 116 | КонецФункции 117 | 118 | // Функция добавляет команду формы 119 | // 120 | // Параметры: 121 | // Форма - ФормаКлиентскогоПриложения 122 | // Имя - Строка, содержит имя команды 123 | // Действие - Строка, содержит имя процедуры обработчика команды 124 | //Для действия по умолчанию см. МодификацияКонфигурацииКлиентПереопределяемый.ВыполнитьПереопределяемуюКоманду 125 | // 126 | // Возвращаемое значение: 127 | // КомандыФормы - созданная команда 128 | // 129 | Функция ДобавитьКоманду(Форма, Имя, Действие = "Подключаемый_ВыполнитьПереопределяемуюКоманду") 130 | 131 | Команда = Форма.Команды.Добавить(Имя); 132 | Команда.Заголовок = ПолучитьЗаголовокПоИмени(Имя); 133 | Команда.Действие = Действие; 134 | Возврат Команда 135 | 136 | КонецФункции 137 | 138 | // Функция добавляет на форму новый элемент типа ПолеФормы 139 | // 140 | // Параметры: 141 | // Форма - ФормаКлиентскогоПриложения 142 | // ПутьКданным - Строка, содержит путь к реквизиту, с которым связан объект 143 | // Родитель - Элемент формы, родитель для добавляемого элемента, если не указан, то добавляется на верхний уровень 144 | // ЭлементПередКоторымВставить - Элемент формы или Число (номер элемента формы, нумерация начинается с 1), перед которым должен быть вставлен новый элемент 145 | //Если не указан, то элемент будет вставлен в конец 146 | //Указание числом места вставки полезно, например, когда элемент нужно вставить в самое начало группы, а второй элемент формы может добавляться программно 147 | // ВидПоля - ВидПоляФормы, по умолчанию ПолеВвода 148 | // Эталон - Элемент формы, свойства которого нужно скопировать, при этом уникальные свойства не копируются (см. переменную ИсключаемыеСвойства внутри функции) 149 | // 150 | // Возвращаемое значение: 151 | // ПолеФормы - созданное поле 152 | // 153 | Функция ДобавитьПоле(Форма, ПутьКданным, Родитель = Неопределено, ЭлементПередКоторымВставить = Неопределено, ВидПоля = Неопределено, Эталон = Неопределено) 154 | 155 | РеквизитСРодителем = ПолучитьРеквизитПоПути(Форма, ПутьКданным); 156 | Реквизит = РеквизитСРодителем.Реквизит; 157 | РодительРеквизита = РеквизитСРодителем.Родитель; 158 | 159 | ИмяЭлемента = ?(РодительРеквизита = Неопределено, Реквизит.Имя, РодительРеквизита.Имя + Реквизит.Имя); 160 | 161 | Если ТипЗнч(Реквизит) = Тип("Объектметаданных") Тогда 162 | ЭтоРеквизитОбъекта = Истина; 163 | Иначе 164 | ЭтоРеквизитОбъекта = Ложь; 165 | КонецЕсли; 166 | 167 | Если ВидПоля = Неопределено И Эталон = Неопределено Тогда 168 | Если ЭтоРеквизитОбъекта Тогда 169 | СвойствоТип = "Тип"; 170 | Иначе 171 | СвойствоТип = "ТипЗначения"; 172 | КонецЕсли; 173 | 174 | Если Реквизит[СвойствоТип].Типы().Количество() = 1 И Реквизит[СвойствоТип].Типы()[0] = Тип("Булево") Тогда 175 | ВидПоля = ВидПоляФормы.ПолеФлажка; 176 | Иначе 177 | ВидПоля = ВидПоляФормы.ПолеВвода; 178 | КонецЕсли; 179 | КонецЕсли; 180 | 181 | Если ТипЗнч(ЭлементПередКоторымВставить) = Тип("Число") Тогда 182 | ГруппаДляПоискаМестаВставки = Родитель; 183 | Если ГруппаДляПоискаМестаВставки = Неопределено Тогда 184 | ГруппаДляПоискаМестаВставки = Форма; 185 | КонецЕсли; 186 | Если ГруппаДляПоискаМестаВставки.ПодчиненныеЭлементы.Количество() < ЭлементПередКоторымВставить Тогда 187 | ЭлементПередКоторымВставить = ГруппаДляПоискаМестаВставки.ПодчиненныеЭлементы.Количество(); 188 | ИначеЕсли ЭлементПередКоторымВставить < 1 Тогда 189 | ЭлементПередКоторымВставить = 1; 190 | КонецЕсли; 191 | ЭлементПередКоторымВставить = ГруппаДляПоискаМестаВставки.ПодчиненныеЭлементы[ЭлементПередКоторымВставить - 1]; 192 | КонецЕсли; 193 | 194 | НовыйЭлемент = Форма.Элементы.Вставить(ИмяЭлемента, Тип("ПолеФормы"), Родитель, ЭлементПередКоторымВставить); 195 | 196 | Если Эталон <> Неопределено Тогда 197 | ИсключаемыеСвойства = Новый Массив; 198 | ИсключаемыеСвойства.Добавить("ПутьКДанным"); 199 | ИсключаемыеСвойства.Добавить("ПутьКДаннымПодвала"); 200 | ИсключаемыеСвойства.Добавить("Заголовок"); 201 | ИсключаемыеСвойства.Добавить("Подсказка"); 202 | ИсключаемыеСвойства.Добавить("РасширеннаяПодсказка"); 203 | ИсключаемыеСвойства.Добавить("Видимость"); 204 | ИсключаемыеСвойства.Добавить("Доступность"); 205 | ИсключаемыеСвойства.Добавить("ТолькоПросмотр"); 206 | ИсключаемыеСвойства.Добавить("СочетаниеКлавиш"); 207 | ИсключаемыеСвойства.Добавить("АктивизироватьПоУмолчанию"); 208 | Если Эталон.Вид = ВидПоляФормы.ПолеВвода Тогда 209 | ИсключаемыеСвойства.Добавить("ВыделенныйТекст"); 210 | ИсключаемыеСвойства.Добавить("СвязьПоТипу"); 211 | ИсключаемыеСвойства.Добавить("ПодсказкаВвода"); 212 | ИсключаемыеСвойства.Добавить("ФормаВыбора"); 213 | ИсключаемыеСвойства.Добавить("ОтметкаНезаполненного"); 214 | ИсключаемыеСвойства.Добавить("АвтоОтметкаНезаполненного"); 215 | КонецЕсли; 216 | ЗаполнитьЗначенияСвойств(НовыйЭлемент, Эталон, , СтрСоединить(ИсключаемыеСвойства, ",")); 217 | КонецЕсли; 218 | 219 | Если ВидПоля <> Неопределено Тогда 220 | НовыйЭлемент.Вид = ВидПоля; 221 | КонецЕсли; 222 | 223 | Если ЭтоРеквизитОбъекта Тогда 224 | Если НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода И Реквизит.ПроверкаЗаполнения = ПроверкаЗаполнения.ВыдаватьОшибку Тогда 225 | НовыйЭлемент.ОтметкаНезаполненного = Истина; 226 | НовыйЭлемент.АвтоОтметкаНезаполненного = Истина; 227 | КонецЕсли; 228 | КонецЕсли; 229 | 230 | НовыйЭлемент.ПутьКДанным = ПутьКДанным; 231 | 232 | Возврат НовыйЭлемент; 233 | 234 | КонецФункции 235 | 236 | // Функция добавляет на форму новый элемент типа КнопкаФормы 237 | // 238 | // Параметры: 239 | // Форма - ФормаКлиентскогоПриложения 240 | // Команда - КомандаФормы 241 | // Родитель - Элемент формы, родитель для добавляемого элемента, если не указан, то добавляется на верхний уровень 242 | // ЭлементПередКоторымВставить - Элемент формы или Число (номер элемента формы, нумерация начинается с 1), перед которым должен быть вставлен новый элемент 243 | //Если не указан, то элемент будет вставлен в конец 244 | //Указание числом места вставки полезно, например, когда элемент нужно вставить в самое начало группы, а второй элемент формы может добавляться программно 245 | // ВидКоманды - ВидКнопкиФормы, по умолчанию ОбычнаяКнопка 246 | // Эталон - Элемент формы, свойства которого нужно скопировать, при этом уникальные свойства не копируются (см. переменную ИсключаемыеСвойства внутри функции) 247 | // 248 | // Возвращаемое значение: 249 | // КнопкаФормы - созданная кнопка 250 | // 251 | Функция ДобавитьКнопку(Форма, Команда, Родитель = Неопределено, ЭлементПередКоторымВставить = Неопределено, ВидКоманды = Неопределено, Эталон = Неопределено) 252 | 253 | Если ВидКоманды = Неопределено И Эталон = Неопределено Тогда 254 | ВидКоманды = ВидКнопкиФормы.ОбычнаяКнопка; 255 | КонецЕсли; 256 | 257 | Если ТипЗнч(ЭлементПередКоторымВставить) = Тип("Число") Тогда 258 | ГруппаДляПоискаМестаВставки = Родитель; 259 | Если ГруппаДляПоискаМестаВставки = Неопределено Тогда 260 | ГруппаДляПоискаМестаВставки = Форма; 261 | КонецЕсли; 262 | Если ГруппаДляПоискаМестаВставки.ПодчиненныеЭлементы.Количество() < ЭлементПередКоторымВставить Тогда 263 | ЭлементПередКоторымВставить = ГруппаДляПоискаМестаВставки.ПодчиненныеЭлементы.Количество(); 264 | ИначеЕсли ЭлементПередКоторымВставить < 1 Тогда 265 | ЭлементПередКоторымВставить = 1; 266 | КонецЕсли; 267 | ЭлементПередКоторымВставить = ГруппаДляПоискаМестаВставки.ПодчиненныеЭлементы[ЭлементПередКоторымВставить - 1]; 268 | КонецЕсли; 269 | 270 | НовыйЭлемент = Форма.Элементы.Вставить(Команда.Имя, Тип("КнопкаФормы"), Родитель, ЭлементПередКоторымВставить); 271 | 272 | Если Эталон <> Неопределено Тогда 273 | ИсключаемыеСвойства = Новый Массив; 274 | ИсключаемыеСвойства.Добавить("ИмяКоманды"); 275 | ИсключаемыеСвойства.Добавить("Заголовок"); 276 | ИсключаемыеСвойства.Добавить("РасширеннаяПодсказка"); 277 | ИсключаемыеСвойства.Добавить("КнопкаПоУмолчанию"); 278 | ИсключаемыеСвойства.Добавить("СочетаниеКлавиш"); 279 | ИсключаемыеСвойства.Добавить("АктивизироватьПоУмолчанию"); 280 | ЗаполнитьЗначенияСвойств(НовыйЭлемент, Эталон, , СтрСоединить(ИсключаемыеСвойства, ",")); 281 | КонецЕсли; 282 | 283 | Если ВидКоманды <> Неопределено Тогда 284 | НовыйЭлемент.Вид = ВидКоманды; 285 | КонецЕсли; 286 | 287 | НовыйЭлемент.ИмяКоманды = Команда.Имя; 288 | 289 | Возврат НовыйЭлемент; 290 | 291 | КонецФункции 292 | 293 | // Функция добавляет реквизит формы и создает на основе его новое поле 294 | // 295 | // Параметры: 296 | // Форма - ФормаКлиентскогоПриложения 297 | // Имя - Строка, содержит имя реквизита 298 | // Тип - Строка типа, Тип или ОписаниеТипов 299 | // Заголовок - Строка, содержит отображаемый текст реквизита 300 | //Если заголовок не задан, то формируется функцией "ПолучитьЗаголовокПоИмени" 301 | // Путь - Строка, содержит путь к реквизиту, не включая имя реквизита 302 | // СохраняемыеДанные - Булево, если Истина - указывает, что это сохраняемый при записи реквизит, по умолчанию Ложь 303 | // Значение - Произвольный, значение, присваиваемое реквизиту после его создания 304 | // Родитель - Элемент формы, родитель для добавляемого элемента, если не указан, то добавляется на верхний уровень 305 | // ЭлементПередКоторымВставить - Элемент формы или Число (номер элемента формы, нумерация начинается с 1), перед которым должен быть вставлен новый элемент 306 | //Если не указан, то элемент будет вставлен в конец 307 | //Указание числом места вставки полезно, например, когда элемент нужно вставить в самое начало группы, а второй элемент формы может добавляться программно 308 | // ВидПоля - ВидПоляФормы, по умолчанию ПолеВвода 309 | // Эталон - Элемент формы, свойства которого нужно скопировать, при этом уникальные свойства не копируются (см. переменную ИсключаемыеСвойства внутри функции) 310 | // 311 | // Возвращаемое значение: 312 | // Структура: 313 | // * РеквизитФормы - созданный реквизит формы 314 | // * ПолеФормы - созданное поле 315 | // 316 | Функция ДобавитьРеквизитИПоле( 317 | Форма, 318 | Имя, Тип, Заголовок = Неопределено, Путь = Неопределено, СохраняемыеДанные = Неопределено, Значение = Неопределено, 319 | Родитель = Неопределено, ЭлементПередКоторымВставить = Неопределено, ВидПоля = Неопределено, Эталон = Неопределено 320 | ) 321 | Реквизит = ДобавитьРеквизит(Форма, Имя, Тип, Заголовок, Путь, СохраняемыеДанные, Значение); 322 | ПутьКДанным = ?(ЗначениеЗаполнено(Реквизит.Путь), Реквизит.Путь + ".", "") + Реквизит.Имя; 323 | Поле = ДобавитьПоле(Форма, ПутьКДанным, Родитель, ЭлементПередКоторымВставить, ВидПоля, Эталон); 324 | Возврат Новый Структура("Реквизит, Поле", Реквизит, Поле); 325 | 326 | КонецФункции 327 | 328 | // Функция добавляет команду формы и создает на основе нее новую кнопку 329 | // 330 | // Параметры: 331 | // Форма - ФормаКлиентскогоПриложения 332 | // Имя - Строка, содержит имя команды 333 | // Действие - Строка, содержит имя процедуры обработчика команды 334 | //Для действия по умолчанию см. МодификацияКонфигурацииКлиентПереопределяемый.ВыполнитьПереопределяемуюКоманду 335 | // Родитель - Элемент формы, родитель для добавляемого элемента, если не указан, то добавляется на верхний уровень 336 | // ЭлементПередКоторымВставить - Элемент формы или Число (номер элемента формы, нумерация начинается с 1), перед которым должен быть вставлен новый элемент 337 | //Если не указан, то элемент будет вставлен в конец 338 | //Указание числом места вставки полезно, например, когда элемент нужно вставить в самое начало группы, а второй элемент формы может добавляться программно 339 | // ВидКоманды - ВидКнопкиФормы, по умолчанию ОбычнаяКнопка 340 | // Эталон - Элемент формы, свойства которого нужно скопировать, при этом уникальные свойства не копируются (см. переменную ИсключаемыеСвойства внутри функции) 341 | // 342 | // Возвращаемое значение: 343 | // Структура: 344 | // * КомандыФормы - созданная команда 345 | // * КнопкаФормы - созданная кнопка 346 | // 347 | Функция ДобавитьКомандуИКнопку( 348 | Форма, 349 | Имя, Действие = "Подключаемый_ВыполнитьПереопределяемуюКоманду", 350 | Родитель = Неопределено, ЭлементПередКоторымВставить = Неопределено, ВидКоманды = Неопределено, Эталон = Неопределено 351 | ) 352 | Команда = ДобавитьКоманду(Форма, Имя, Действие); 353 | Кнопка = ДобавитьКнопку(Форма, Команда, Родитель, ЭлементПередКоторымВставить, ВидКоманды, Эталон); 354 | Возврат Новый Структура("Команда, Кнопка", Команда, Кнопка); 355 | 356 | КонецФункции 357 | 358 | // Функция добавляет на форму новый элемент типа ГруппаФормы 359 | // 360 | // Параметры: 361 | // Форма - ФормаКлиентскогоПриложения 362 | // ИмяЭлемента - Строка 363 | // Родитель - Элемент формы, родитель для добавляемого элемента, если не указан, то добавляется на верхний уровень 364 | // ЭлементПередКоторымВставить - Элемент формы или Число (номер элемента формы, нумерация начинается с 1), перед которым должен быть вставлен новый элемент 365 | //Если не указан, то элемент будет вставлен в конец 366 | //Указание числом места вставки полезно, например, когда элемент нужно вставить в самое начало группы, а второй элемент формы может добавляться программно 367 | // ВидГруппы - ВидГруппыФормы, по умолчанию ОбычнаяГруппа 368 | // Эталон - Элемент формы, свойства которого нужно скопировать, при этом уникальные свойства не копируются (см. переменную ИсключаемыеСвойства внутри функции) 369 | // 370 | // Возвращаемое значение: 371 | // ГруппаФормы - созданная группа 372 | // 373 | Функция ДобавитьГруппу(Форма, ИмяЭлемента, Родитель = Неопределено, ЭлементПередКоторымВставить = Неопределено, ВидГруппы = Неопределено, Эталон = Неопределено) 374 | 375 | Если ВидГруппы = Неопределено И Эталон = Неопределено Тогда 376 | ВидГруппы = ВидГруппыФормы.ОбычнаяГруппа; 377 | КонецЕсли; 378 | 379 | Если ТипЗнч(ЭлементПередКоторымВставить) = Тип("Число") Тогда 380 | ГруппаДляПоискаМестаВставки = Родитель; 381 | Если ГруппаДляПоискаМестаВставки = Неопределено Тогда 382 | ГруппаДляПоискаМестаВставки = Форма; 383 | КонецЕсли; 384 | Если ГруппаДляПоискаМестаВставки.ПодчиненныеЭлементы.Количество() < ЭлементПередКоторымВставить Тогда 385 | ЭлементПередКоторымВставить = ГруппаДляПоискаМестаВставки.ПодчиненныеЭлементы.Количество(); 386 | ИначеЕсли ЭлементПередКоторымВставить < 1 Тогда 387 | ЭлементПередКоторымВставить = 1; 388 | КонецЕсли; 389 | ЭлементПередКоторымВставить = ГруппаДляПоискаМестаВставки.ПодчиненныеЭлементы[ЭлементПередКоторымВставить - 1]; 390 | КонецЕсли; 391 | 392 | НовыйЭлемент = Форма.Элементы.Вставить(ИмяЭлемента, Тип("ГруппаФормы"), Родитель, ЭлементПередКоторымВставить); 393 | 394 | Если Эталон <> Неопределено Тогда 395 | ИсключаемыеСвойства = Новый Массив; 396 | ИсключаемыеСвойства.Добавить("Заголовок"); 397 | ИсключаемыеСвойства.Добавить("Подсказка"); 398 | ИсключаемыеСвойства.Добавить("СочетаниеКлавиш"); 399 | ИсключаемыеСвойства.Добавить("ПодчиненныеЭлементы"); 400 | ЗаполнитьЗначенияСвойств(НовыйЭлемент, Эталон, , СтрСоединить(ИсключаемыеСвойства, ",")); 401 | КонецЕсли; 402 | 403 | Если ВидГруппы <> Неопределено Тогда 404 | НовыйЭлемент.Вид = ВидГруппы; 405 | КонецЕсли; 406 | 407 | НовыйЭлемент.Заголовок = ПолучитьЗаголовокПоИмени(ИмяЭлемента); 408 | 409 | Возврат НовыйЭлемент; 410 | 411 | КонецФункции 412 | 413 | #КонецОбласти 414 | 415 | #Область ДоработкаФорм_СлужебныйПрограммныйИнтерфейс 416 | 417 | // Возвращает произвольный реквизит Формы по переданному пути 418 | // Если реквизит относится к метаданным, то возвращается метаданное 419 | // 420 | // Параметры: 421 | // Форма - ФормаКлиентскогоПриложения 422 | // Путь - Строка, путь к реквизиту формы, разделенный точками (Например, Объект.Товары.Спецификация) 423 | // 424 | // Возвращаемое значение: 425 | // Структура или Неопределено, если реквизит не найден: 426 | // * Реквизит - РеквизитФормы или ОбъектМетаданных (реквизит объекта) 427 | // * Родитель - РеквизитФормы, ОбъектМетаданных (реквизит объекта) или Неопределено, если родитель (табличная часть, ТЗ или ДЗ) отсутствует 428 | // 429 | Функция ПолучитьРеквизитПоПути(Форма, Путь) 430 | 431 | СтруктураВозврата = Новый Структура("Реквизит, Родитель"); 432 | ПутьРазделенныйТочками = СтрРазделить(Путь, "."); 433 | Если ПутьРазделенныйТочками.Количество() > 1 И ПутьРазделенныйТочками[0] = "Объект" Тогда 434 | ПутьРазделенныйТочками.Удалить(0); 435 | Если ПутьРазделенныйТочками.Количество() = 1 Тогда 436 | СтруктураВозврата.Реквизит = Форма.РеквизитФормыВЗначение("Объект").Метаданные().Реквизиты[ПутьРазделенныйТочками[0]]; 437 | Возврат СтруктураВозврата; 438 | Иначе 439 | СтруктураВозврата.Родитель = Форма.РеквизитФормыВЗначение("Объект").Метаданные().ТабличныеЧасти[ПутьРазделенныйТочками[0]]; 440 | Если СтруктураВозврата.Родитель.Реквизиты.Найти(ПутьРазделенныйТочками[1]) <> Неопределено Тогда 441 | СтруктураВозврата.Реквизит = СтруктураВозврата.Родитель.Реквизиты[ПутьРазделенныйТочками[1]]; 442 | Иначе 443 | РеквизитыТаблицы = Форма.ПолучитьРеквизиты("Объект." + СтруктураВозврата.Родитель.Имя); 444 | Для Каждого Стр Из РеквизитыТаблицы Цикл 445 | Если Стр.Имя = ПутьРазделенныйТочками[1] Тогда 446 | СтруктураВозврата.Реквизит = Стр; 447 | Прервать; 448 | КонецЕсли; 449 | КонецЦикла; 450 | КонецЕсли; 451 | Возврат СтруктураВозврата; 452 | КонецЕсли; 453 | КонецЕсли; 454 | МассивРеквизитов = Форма.ПолучитьРеквизиты(); 455 | Для Каждого Стр Из МассивРеквизитов Цикл 456 | Если ПутьРазделенныйТочками.Количество() > 1 И 457 | ((Стр.ТипЗначения.Типы().Количество() = 1 И Стр.ТипЗначения.Типы()[0] = Тип("ТаблицаЗначений")) 458 | ИЛИ 459 | (Стр.ТипЗначения.Типы().Количество() = 1 И Стр.ТипЗначения.Типы()[0] = Тип("ДеревоЗначений"))) Тогда 460 | 461 | Если Стр.Имя = ПутьРазделенныйТочками[0] Тогда 462 | СтруктураВозврата.Родитель = Стр; 463 | Иначе 464 | Продолжить; 465 | КонецЕсли; 466 | РеквизитыТаблицы = Форма.ПолучитьРеквизиты(Стр.Имя); 467 | Для Каждого СтрСтр Из РеквизитыТаблицы Цикл 468 | Если СтрСтр.Имя = ПутьРазделенныйТочками[1] Тогда 469 | СтруктураВозврата.Реквизит = СтрСтр; 470 | Возврат СтруктураВозврата; 471 | КонецЕсли; 472 | КонецЦикла; 473 | Иначе 474 | Если Стр.Имя = Путь Тогда 475 | СтруктураВозврата.Реквизит = Стр; 476 | Возврат СтруктураВозврата; 477 | КонецЕсли; 478 | КонецЕсли; 479 | КонецЦикла; 480 | 481 | КонецФункции 482 | 483 | // Функция возвращает заголовок по наименованию так, как это происходит в конфигураторе (точное соответствие) 484 | // При этом есть возможность убрать префикс, чтобы заголовок формировался без него 485 | // Правила преобразования: 486 | // 0) удаляется префикс при необходимости (вместе с разделителем) 487 | // 1) символ "_" заменяется пробелом, при этом лишние пробелы удаляются 488 | // 2) первая буква становится прописной 489 | // 3) перед всеми прописными буквами кроме первой ставится пробел 490 | // * если прописными буквы идут друг за другом более, чем 2 раза, то пробел ставится только перед первой 491 | // 4) все прописные буквы кроме первой превращаются в строчные 492 | // * если прописные буквы идут друг за другом более, чем 2 раза, то регистр букв не меняется 493 | // * если прописная буква является единственным символом или находится в конце строки, то регистр букв не меняется 494 | // 495 | // Параметры: 496 | // Имя - Строка, имя написаное в стиле CamelCase с возможным указанием префикса (например, "дк_ОформитьДокументыПроизводства") 497 | // РазделительПрефиксаОтИмени - Строка, по данному разделителю удаляется префикс 498 | // КонкретныйПрефикс - Строка, если значение заполнено, то данный префикс ищется перед разделителем, и только тогда префикс удаляется 499 | //Если значение не заполнено, то префикс определяется автоматически перед разделителем 500 | // 501 | Функция ПолучитьЗаголовокПоИмени(Имя, РазделительПрефиксаОтИмени = "_", КонкретныйПрефикс = "") 502 | 503 | ИмяБезПрефикса = Имя; 504 | Если НЕ ЗначениеЗаполнено(КонкретныйПрефикс) И ЗначениеЗаполнено(РазделительПрефиксаОтИмени) Тогда 505 | КонкретныйПрефикс = Лев(Имя, Найти(Имя, РазделительПрефиксаОтИмени) - 1); 506 | КонецЕсли; 507 | СтрокаПередКоторойВключаяУдалитьСимволы = КонкретныйПрефикс + РазделительПрефиксаОтИмени; 508 | Если ЗначениеЗаполнено(СтрокаПередКоторойВключаяУдалитьСимволы) Тогда 509 | НачалоНужнойСтроки = Найти(Имя, СтрокаПередКоторойВключаяУдалитьСимволы); 510 | Если Лев(Имя, СтрДлина(СтрокаПередКоторойВключаяУдалитьСимволы)) = СтрокаПередКоторойВключаяУдалитьСимволы Тогда 511 | ИмяБезПрефикса = Прав(Имя, СтрДлина(Имя) - СтрДлина(СтрокаПередКоторойВключаяУдалитьСимволы)); 512 | КонецЕсли; 513 | КонецЕсли; 514 | 515 | Заголовок = ""; 516 | ПредСимвол = ""; 517 | Для Сч = 1 По СтрДлина(ИмяБезПрефикса) Цикл 518 | Символ = Сред(ИмяБезПрефикса, Сч, 1); 519 | Если Символ = "_" Тогда 520 | Символ = ?(ПредСимвол = Символы.НПП, "", Символы.НПП); 521 | КонецЕсли; 522 | Заголовок = Заголовок + Символ; 523 | ПредСимвол = ?(Символ = "", Символы.НПП, Символ); 524 | КонецЦикла; 525 | 526 | Заголовок = СокрЛП(Заголовок); 527 | 528 | ЗаголовокДоработанный = ""; 529 | ПредСимволСтрочный = ""; 530 | ПредПредСимволСтрочный = ""; 531 | ПредСимвол = ""; 532 | Для Сч = 1 По СтрДлина(Заголовок) Цикл 533 | Символ = Сред(Заголовок, Сч, 1); 534 | СледСимвол = ?(Сч + 1 <= СтрДлина(Заголовок), Сред(Заголовок, Сч + 1, 1), ""); 535 | СледСимволСтрочный = ?(СледСимвол = ВРег(СледСимвол), СледСимвол, ""); 536 | СледСледСимвол = ?(Сч + 2 <= СтрДлина(Заголовок), Сред(Заголовок, Сч + 2, 1), ""); 537 | Если СледСимволСтрочный <> "" Тогда 538 | СледСледСимволСтрочный = ?(СледСледСимвол = ВРег(СледСледСимвол), СледСледСимвол, ""); 539 | Иначе 540 | СледСледСимволСтрочный = ""; 541 | КонецЕсли; 542 | СимволДляКонкатенации = Символ; 543 | БылРазрыв = Ложь; 544 | Если Сч > 1 И ВРег(Символ) = Символ И ПредСимвол <> Символы.НПП И Символ <> Символы.НПП 545 | И (СтрДлина(СледСимволСтрочный + СледСледСимволСтрочный + ПредСимволСтрочный + ПредПредСимволСтрочный) < 2 546 | ИЛИ Нрег(ПредСимвол) = ПредСимвол) Тогда 547 | 548 | Если НЕ(СтрДлина(СледСимволСтрочный + ПредСимволСтрочный) > 0 И СледСимвол = "") Тогда 549 | ЗаголовокДоработанный = ЗаголовокДоработанный + Символы.НПП; 550 | БылРазрыв = Истина; 551 | КонецЕсли; 552 | СимволДляКонкатенации = ?(СтрДлина(СледСимволСтрочный + ПредСимволСтрочный) > 0 И (НЕ БылРазрыв ИЛИ СледСимволСтрочный <> ""), Символ, НРег(Символ)); 553 | Если БылРазрыв И СледСимволСтрочный <> "" И СледСледСимволСтрочный = "" И СледСледСимвол <> "" Тогда 554 | СимволДляКонкатенации = НРег(СимволДляКонкатенации); 555 | ИначеЕсли СледСимвол = "" И БылРазрыв Тогда 556 | СимволДляКонкатенации = Символ; 557 | КонецЕсли; 558 | 559 | КонецЕсли; 560 | ЗаголовокДоработанный = ЗаголовокДоработанный + СимволДляКонкатенации; 561 | ПредПредСимволСтрочный = ?(ПредСимвол = ВРег(ПредСимвол), ПредСимвол, ""); 562 | ПредСимвол = Символ; 563 | ПредСимволСтрочный = ?(Символ = ВРег(Символ), Символ, ""); 564 | КонецЦикла; 565 | 566 | Возврат Врег(Лев(ЗаголовокДоработанный, 1)) + Сред(ЗаголовокДоработанный, 2); 567 | 568 | КонецФункции 569 | 570 | #КонецОбласти 571 | 572 | 573 | // Эту функцию корректнее размещать в клиентСерверном модуле, так как необходимость ее вызова возможна и с клиента 574 | 575 | // Возвращает вид метаданных, тип объекта и имя формы строкой 576 | // 577 | // Параметры: 578 | // ПолноеИмяФормы - Строка, имя формы (Форма.ИмяФормы) 579 | // 580 | // Возвращаемое значение: 581 | // Структура: 582 | // * ВидМетаданных - Строка, содержит вид метаданных (например, "Документ", "Справочник", "ОбщаяФорма") 583 | // * ТипОбъекта - Строка, содержит тип объекта (например, "ЗаказКлиента", "Номенклатура", "Отчет") 584 | //Для общих форм тип объекта Неопределено 585 | // * ИмяФормы - Строка, содержит конкретное имя формы (например, "ФормаДокумента", "ФормаЭлемента", "ФормаОтчета", "СчитываниеКартыЛояльности") 586 | // 587 | Функция ПолучитьСтруктурированноеОписаниеИмениФормы(ПолноеИмяФормы) Экспорт 588 | 589 | ЧастиИмениФормыРазделенныеТочками = СтрРазделить(ПолноеИмяФормы, "."); 590 | // Для разных типов объектов путь к форме может отличаться (например, общие формы) 591 | Если ЧастиИмениФормыРазделенныеТочками.Количество() = 2 Тогда 592 | ВидМетаданных = ЧастиИмениФормыРазделенныеТочками[0]; 593 | ТипОбъекта = Неопределено; 594 | ИмяФормы = ЧастиИмениФормыРазделенныеТочками[1]; 595 | ИначеЕсли ЧастиИмениФормыРазделенныеТочками.Количество() = 3 Тогда 596 | ВидМетаданных = ЧастиИмениФормыРазделенныеТочками[0]; 597 | ТипОбъекта = ЧастиИмениФормыРазделенныеТочками[1]; 598 | ИмяФормы = ЧастиИмениФормыРазделенныеТочками[2]; 599 | Иначе 600 | ВидМетаданных = ЧастиИмениФормыРазделенныеТочками[0]; 601 | ТипОбъекта = ЧастиИмениФормыРазделенныеТочками[1]; 602 | ИмяФормы = ЧастиИмениФормыРазделенныеТочками[3]; 603 | КонецЕсли; 604 | 605 | Возврат Новый Структура("ВидМетаданных, ТипОбъекта, ИмяФормы", ВидМетаданных, ТипОбъекта, ИмяФормы); 606 | 607 | КонецФункции 608 | --------------------------------------------------------------------------------