InquirerNCR hospitals, emergency teams on alert for ‘Undas’ESPN DeportesLa Águilas reaccionan pronto y marcan el empateDaily MaverickBOOK EXCERPT: Sandstone Estates – where steam locomotives bring SA railway history to lifeESPNContreras earns World Series MVP honors with .381 average, 10 ABS overturnsPunchPolice nab NSCDC officer for shooting in Abuja market한겨레해킹 징후 알고도 대응 소홀…대교, 65만명 개인정보 유출에 과징금 32억5500만원CNN TürkTürkiye Cumhuriyet 103 yaşında!ZDF heuteEntdecken Sie das ZDF-Nachrichtenstudioسكاي نيوز عربيةبعد حادث إسبانيا.. كيف تحمي القطارات السريعة ركابها؟The Sydney Morning HeraldLeaked letter reveals growing Labor rift over Kimberley frackingMalay MailTrump administration dealt court blow as judge rejects bid to block 20,000 California voters ahead of midtermsSportstarLeague Cup 2026-27 Quarterfinals draw: Find out who Liverpool, Manchester City will face
The Daily Newsstand · Free, Always
Thursday, October 29, 2026

Архитектура 1С для новичков: Строим первую внешнюю обработку и клиент-серверный мост. Часть вторая

Translate

В первой части мы разобрались, почему сервер 1С «слеп» к файлам на вашем диске C: , и подготовили поле ввода для пути к файлу. Пользователь нажал на заветные три точки ... и выбрал документ. Путь к файлу мы научились делать за 3 шага. Что дальше? Теперь нам нужна большая, красивая кнопка, которая заставит этот файл оторваться от вашего компьютера, улететь на сервер, превратиться там в данные базы и вернуть нам красивое окошко с сообщением. Давайте по шагам разберем, как спроектировать это и запустить клиент-серверный мост.

Шаг 4. Создаем кнопку действия «Выполнить загрузку». Просто нарисовать кнопку на экране мало — нужно объяснить платформе, что должно произойти при клике.

В редакторе формы нашей внешней обработки переходим на вкладку Команды (она находится в правом верхнем окне, прямо рядом с «Реквизитами»). Нажимаем зелёный плюс «Добавить» и называем нашу команду просто и понятно: Загрузить. Берем эту команду мышкой и перетаскиваем в левое верхнее окно Элементы, прямо под наше поле с путем к файлу.

На форме появится кнопка. Выделите её, откройте свойства (Alt + Enter) и в поле Заголовок укажите текст, который увидит пользователь: Загрузить.

Шаг 5. Выбор типа обработчика события. Теперь необходимо связать созданную команду с программным кодом. В свойствах команды найдите строку Действие и нажмите на пиктограмму с лупой. Платформа откроет диалоговое окно выбора. Из предложенного списка необходимо выбрать пункт: «Создать на клиенте и процедуру на сервере без контекста».

Давайте разберем, почему платформа предлагает разделение и почему выбор директивы «без контекста» (&НаСервереБезКонтекста) является наиболее правильным.

Почему процедура создается и на клиенте, и на сервере?

Нажатие кнопки пользователем — это действие, которое физически происходит в интерфейсе программы, то есть на Клиенте. Однако клиентская процедура не имеет прямого доступа к серверным вычислениям и механизмам базы данных. Для этого управление необходимо передать на Сервер. Данный тип обработчика автоматически создает пару связанных процедур, обеспечивая правильную передачу данных между уровнями архитектуры.

 В чем разница между «на сервере» и «на сервере без контекста»?

Когда вызывается обычная процедура &НаСервере, платформа 1С берет со стороны клиента абсолютно все данные формы (все реквизиты, таблицы, элементы интерфейса), упаковывает их и пересылает на сервер. Сервер тратит время и память на обработку этого объема информации, а затем отправляет всё обратно на клиент. Это называется «передачей контекста формы».

Если выбрать &НаСервереБезКонтекста:Платформа выполняет «легкий» вызов. Сервер получает только те переменные, которые мы сами явно передадим ему в параметрах. Контекст формы (интерфейс, лишние реквизиты) остается нетронутым на клиенте. Скорость выполнения операции возрастает в разы, так как программе не приходится гонять лишние мегабайты данных по сети между клиентом и сервером. Сервер получит только те переменные, которые передадим ему в параметрах (в нашем случае — файл). Сама форма и её элементы останутся на клиенте, не нагружая сеть и память сервера лишней работой. Поэтому использование директивы БезКонтекста — это стандарт качественной и производительной разработки в 1С. Нажимаем«ОК» платформа сгенерирует в модуле формы шаблоны двух процедур, готовых к написанию алгоритма.

После того как платформа создала пару процедур (клиентскую и бесконтекстную серверную), у начинающих разработчиков часто возникает вопрос: «Мы же создали серверную процедуру, почему мы не можем сразу передать туда строку с путем к файлу и начать его читать?»

Нет, сразу написать туда весь код чтения файла нельзя. И в этом кроется главная архитектурная ловушка для новичков. Когда платформа генерирует пустой шаблон процедуры &НаСервереБезКонтекста, может возникнуть соблазн сразу прописать туда привычный код (например, ТабДок.Прочитать(ПутьКФайлу)). Но программа мгновенно выдаст ошибку.

Причина кроется в строгих правилах безопасности и изоляции уровней архитектуры 1С.

Сервер не имеет доступа к вашему диску: Ваша серверная процедура выполняется в сеансе операционной системы на сервере приложений 1С. Если передадим на сервер обычную строку C:\Users\Nina\Desktop\Лист Microsoft Excel.xlsx, сервер попытается найти этот файл на своем собственном жестком диске (там, где физически установлена серверная часть 1С), а не на вашем персональном компьютере. Естественно, он выдаст ошибку «Файл не найден». Бесконтекстный вызов изолирован от формы: Поскольку мы выбрали директиву БезКонтекста, серверная процедура не видит саму форму нашей обработки. Она не может напрямую «посмотреть» в реквизит ПутьКФайлу на экране. Она видит только то, что мы передадим ей «в руках» через параметры. Именно поэтому мы не можем сразу приступить к разбору данных на сервере.

 Шаг 6. Прежде чем написать код нужно понять еще один нюанс. В современных версиях платформы 1С (начиная с 8.3.15) старая и привычная функция ПоместитьФайлВоВременноеХранилище() признана устаревшей. Браузеры и операционные системы больше не разрешают программам «намертво» замораживать интерфейс пользователя, пока тяжелый файл летит по сети на сервер. Платформа требует, чтобы загрузка происходила в асинхронном режиме. Это значит, что файл отправляется в фоне, а программа ждет специального сигнала о том, что передача завершена.

Именно из-за этого современного правила безопасности наш мост усложняется: к стандартной паре процедур (на клиенте и на сервере без контекста) добавляется третье промежуточное звено — процедура обратного вызова (или завершения).

Теперь мост в клиент-серверной архитектуре и управляемых формах выглядит так:

1. Процедура на клиенте запускает фоновую отправку файла и говорит системе: «Как только файл долетит до сервера, автоматически передай управление процедуре завершения». И сама сразу закрывается.

2. Процедура завершения на клиенте встречает текстовый документ (ссылку) и передает его дальше. Процедура завершения ничего на сервер не записывает. Сам файл в эту строку записывает встроенная функция платформы. Например, в коде этот адрес выглядит как текстовая строка: e1cib/tempstorage/89a557bb-6927-4bda —  документ по сети еще раз передавать не нужно, сервер найдет его в памяти именно по этому идентификатору.

Как сервер подхватывает эту строку?

Сама по себе серверная функция не узнает о появлении файла в памяти. Поэтому наша процедура завершения делает ключевой шаг: она вызывает бесконтекстную функцию сервера и передает полученную адресную строку в качестве параметра — ЗагрузитьДанныеНаСервере(РезультатПомещения.Адрес).

3. Функция на сервере без контекста по временному адресу сохраняет файл к себе на сервер с созданным адресом, выполняет ту обработку, которую мы пропишем в коде, и возвращает на клиент ровно то сообщение, которое мы написали.

Шаг 7. Теперь, когда логика клиент-серверного моста понятна, реализуем её в коде .  Скопируйте и вставьте этот код:

&НаСервереБезКонтекста
Функция ЗагрузитьДанныеНаСервере(Знач АдресХранилища)
	
	// 1. Сервер по полученному трек-номеру (адресной строке) находит файл в памяти
	ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(АдресХранилища);
	
	// 2. Выполняет ту обработку, которую мы пропишем в коде:
	
	// Создаем на диске сервера пустой файл с расширением xlsx
	ИмяВременногоФайлаСервер = ПолучитьИмяВременногоФайла("xlsx");
	
	// Записываем бинарное содержимое «письма» в этот файл
	ДвоичныеДанныеФайла.Записать(ИмяВременногоФайлаСервер);
	
	// Инициализируем табличный документ 1С для парсинга ячеек Excel
	ТабличныйДокумент = Новый ТабличныйДокумент;
	
	Попытка
		// Сервер считывает внутреннюю структуру Excel-файла
		ТабличныйДокумент.Прочитать(ИмяВременногоФайлаСервер, СпособЧтенияЗначенийТабличногоДокумента.Текст);
		
		// [Именно здесь, ниже этой строки, пишется цикл перебора строк:
		// Для НомерСтроки = 1 По ТабличныйДокумент.ВысотаТаблицы Цикл ...]
		
		ТекстОтвета = "Файл успешно сохранен на сервере";
		
	Исключение
	// ИСПРАВЛЕНО: Используем стандартный метод платформы ПодробноеПредставлениеОшибки
	ТекстОтвета = "Ошибка обработки файла: " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;


	// Обязательно удаляем за собой временный файл с диска сервера, чтобы не засорять память
	УдалитьФайлы(ИмяВременногоФайлаСервер);
	
	// 3. Возвращаем результат обработки на Клиент
	Возврат ТекстОтвета;
	
КонецФункции


 
 

&НаКлиенте
Процедура ВыполнитьЗагрузку(Команда)
	
	Если ПустаяСтрока(ПутьКФайлу) Тогда
		ПоказатьПредупреждение(, "Пожалуйста, выберите файл Excel или MXL для загрузки!");
		Возврат;
	КонецЕсли;
	
	Сообщить("--- Запуск умного импорта файла ---");
	
	// Передаем параметры напрямую в метод, убрав лишнее объявление типа
	ОписаниеОповещения = Новый ОписаниеОповещения("ВыполнитьЗагрузкуЗавершение", ЭтотОбъект);
	
	НачатьПомещениеФайлаНаСервер(ОписаниеОповещения, , , , ПутьКФайлу, УникальныйИдентификатор);

КонецПроцедуры







&НаКлиенте
Процедура ВыполнитьЗагрузкуЗавершение(РезультатПомещения, ДополнительныеПараметры) Экспорт

	// ИСПРАВЛЕНО: Убрали несуществующее свойство ХранениеВыполнено
	Если РезультатПомещения = Неопределено Тогда
		ПоказатьПредупреждение(, "Ошибка при передаче файла на сервер или операция отменена!");
		Возврат;
	КонецЕсли;
	
	// Передаем серверу чистую адресную строку
	ТекстСообщения = ЗагрузитьДанныеНаСервере(РезультатПомещения.Адрес);
	
	// Выводим пользователю ровно то сообщение, которое вернул сервер
	ПоказатьПредупреждение(, ТекстСообщения);

КонецПроцедуры

Шаг 8. Тестируем готовую форму в режиме «1С:Предприятие»

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

Сохраните ваш файл (Файл — Сохранить как...) на рабочий стол. Он запишется в формате .epf.

Запустите вашу базу 1С в обычном пользовательском режиме (1С:Предприятие).

Нажмите Главное меню — Файл — Открыть и выберите ваш сохраненный файл с рабочего стола и нажмите на созданную кнопку действия «Выполнить загрузку».

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

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.