// MIT License // Copyright (c) 2023 Anton Tsitavets // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // https://github.com/Bayselonarrend/OpenIntegrations // BSLLS:LatinAndCyrillicSymbolInWord-off // BSLLS:IncorrectLineBreak-off // Раскомментировать, если выполняется OneScript #Использовать "../../tools" #Область ПрограммныйИнтерфейс #Область РаботаСФайламиИКаталогами // Получить информацию об объекте // Получает информацию о папке или файле по ID // // Параметры: // Токен - Строка - Токен - token // Идентификатор - Строка - Идентификатор файла/каталога - object // // Возвращаемое значение: // Соответствие Из КлючИЗначение - сериализованный JSON ответа от Google Функция ПолучитьИнформациюОбОбъекте(Знач Токен, Знач Идентификатор) Экспорт OPI_ПреобразованиеТипов.ПолучитьСтроку(Токен); OPI_ПреобразованиеТипов.ПолучитьСтроку(Идентификатор); Заголовки = OPI_GoogleWorkspace.ПолучитьЗаголовокАвторизации(Токен); URL = "https://www.googleapis.com/drive/v3/files/" + Идентификатор; Параметры = Новый Структура; Параметры.Вставить("fields", "*"); Ответ = OPI_Инструменты.Get(URL, Параметры, Заголовки); Возврат Ответ; КонецФункции // Получить список каталогов // Получает список каталогов диска // // Параметры: // Токен - Строка - Токен - token // ИмяСодержит - Строка - Отбор по имени - querry // Подробно - Булево - Добавляет список файлов к полям каталога - depth // // Возвращаемое значение: // Соответствие Из КлючИЗначение - Массив соответствий каталогов Функция ПолучитьСписокКаталогов(Знач Токен, Знач ИмяСодержит = "", Знач Подробно = Ложь) Экспорт OPI_ПреобразованиеТипов.ПолучитьСтроку(Токен); OPI_ПреобразованиеТипов.ПолучитьСтроку(ИмяСодержит); OPI_ПреобразованиеТипов.ПолучитьБулево(Подробно); Заголовки = OPI_GoogleWorkspace.ПолучитьЗаголовокАвторизации(Токен); МассивОбъектов = Новый Массив; Отбор = Новый Массив; Отбор.Добавить("mimeType = 'application/vnd.google-apps.folder'"); Если ЗначениеЗаполнено(ИмяСодержит) Тогда Отбор.Добавить("name contains '" + ИмяСодержит + "'"); КонецЕсли; ПолучитьСписокОбъектовРекурсивно(Заголовки, МассивОбъектов, Подробно, Отбор); Если Подробно Тогда РазложитьОбъектыПодробно(Токен, МассивОбъектов); КонецЕсли; Возврат МассивОбъектов; КонецФункции // Получить список файлов // Получает список файлов // // Параметры: // Токен - Строка - Токен - token // ИмяСодержит - Строка - Отбор по имени - querry // Каталог - Строка - Отбор по ID каталога родителя - catalog // // Возвращаемое значение: // Соответствие Из КлючИЗначение - Массив соответствий файлов Функция ПолучитьСписокФайлов(Знач Токен, Знач ИмяСодержит = "", Знач Каталог = "") Экспорт OPI_ПреобразованиеТипов.ПолучитьСтроку(Токен); OPI_ПреобразованиеТипов.ПолучитьСтроку(ИмяСодержит); OPI_ПреобразованиеТипов.ПолучитьСтроку(Каталог); Заголовки = OPI_GoogleWorkspace.ПолучитьЗаголовокАвторизации(Токен); МассивОбъектов = Новый Массив; Отбор = Новый Массив; Отбор.Добавить("mimeType != 'application/vnd.google-apps.folder'"); Если ЗначениеЗаполнено(ИмяСодержит) Тогда Отбор.Добавить("name contains '" + ИмяСодержит + "'"); КонецЕсли; Если ЗначениеЗаполнено(Каталог) Тогда Отбор.Добавить("'" + Каталог + "' in parents"); КонецЕсли; ПолучитьСписокОбъектовРекурсивно(Заголовки, МассивОбъектов, , Отбор); Возврат МассивОбъектов; КонецФункции // Загрузить файл // Загружает файл на диск // // Параметры: // Токен - Строка - Токен - token // Файл - ДвоичныеДанные,Строка - Загружаемый файл - file // Описание - Соответствие Из КлючИЗначение - См. ПолучитьОписаниеФайла - props - JSON описания или путь к .json // // Возвращаемое значение: // Соответствие Из КлючИЗначение - сериализованный JSON ответа от Google Функция ЗагрузитьФайл(Знач Токен, Знач Файл, Знач Описание) Экспорт Возврат УправлениеФайлом(Токен, Файл, Описание); КонецФункции // Создать папку // Создает пустой каталог на диске // // Параметры: // Токен - Строка - Токен - token // Имя - Строка - Имя папки - title // Родитель - Строка - Родитель - catalog // // Возвращаемое значение: // Соответствие Из КлючИЗначение - сериализованный JSON ответа от Google Функция СоздатьПапку(Знач Токен, Знач Имя, Знач Родитель = "") Экспорт OPI_ПреобразованиеТипов.ПолучитьСтроку(Токен); OPI_ПреобразованиеТипов.ПолучитьСтроку(Имя); OPI_ПреобразованиеТипов.ПолучитьСтроку(Родитель); Описание = Новый Соответствие; Описание.Вставить("MIME" , "application/vnd.google-apps.folder"); Описание.Вставить("Имя" , Имя); Описание.Вставить("Описание", ""); Описание.Вставить("Родитель", ?(ЗначениеЗаполнено(Родитель), Родитель, "root")); Возврат УправлениеФайлом(Токен, , Описание); КонецФункции // Скачать файл // Получает файл по ID // // Параметры: // Токен - Строка - Токен - token // Идентификатор - Строка - Идентификатор файла - object // // Возвращаемое значение: // Соответствие Из КлючИЗначение - сериализованный JSON ответа от Google Функция СкачатьФайл(Знач Токен, Знач Идентификатор) Экспорт OPI_ПреобразованиеТипов.ПолучитьСтроку(Токен); OPI_ПреобразованиеТипов.ПолучитьСтроку(Идентификатор); Заголовки = OPI_GoogleWorkspace.ПолучитьЗаголовокАвторизации(Токен); URL = "https://www.googleapis.com/drive/v3/files/" + Идентификатор; Параметры = Новый Соответствие; Параметры.Вставить("alt", "media"); Ответ = OPI_Инструменты.Get(URL, Параметры , Заголовки); Возврат Ответ; КонецФункции // Скоприровать объект // Копирует файл или каталог // // Параметры: // Токен - Строка - Токен - token // Идентификатор - Строка - Идентификатор объекта - object // НовоеИмя - Строка - Новое имя объекта - title // НовыйРодитель - Строка - Новый каталог размещения - catalog // // Возвращаемое значение: // Соответствие Из КлючИЗначение - сериализованный JSON ответа от Google Функция СкопироватьОбъект(Знач Токен, Знач Идентификатор, Знач НовоеИмя = "", Знач НовыйРодитель = "") Экспорт OPI_ПреобразованиеТипов.ПолучитьСтроку(Токен); OPI_ПреобразованиеТипов.ПолучитьСтроку(НовоеИмя); OPI_ПреобразованиеТипов.ПолучитьСтроку(Идентификатор); OPI_ПреобразованиеТипов.ПолучитьСтроку(НовыйРодитель); Заголовки = OPI_GoogleWorkspace.ПолучитьЗаголовокАвторизации(Токен); URL = "https://www.googleapis.com/drive/v3/files/" + Идентификатор + "/copy"; Параметры = Новый Структура; Если ЗначениеЗаполнено(НовоеИмя) Тогда Параметры.Вставить("name", НовоеИмя); КонецЕсли; Если ЗначениеЗаполнено(НовыйРодитель) Тогда МассивРодителей = Новый Массив; МассивРодителей.Добавить(НовыйРодитель); Параметры.Вставить("parents", МассивРодителей); КонецЕсли; Ответ = OPI_Инструменты.Post(URL, Параметры , Заголовки, Истина); Возврат Ответ; КонецФункции // Обновить файл // Обновляет двоичные данные файла // // Параметры: // Токен - Строка - Токен - token // Идентификатор - Строка - Идентификатор обновляемого объекта - object // Файл - ДвоичныеДанные,Строка - Файл источник обновления - file // НовоеИмя - Строка - Новое имя файла (если необходимо) - title // // Возвращаемое значение: // Соответствие Из КлючИЗначение - сериализованный JSON ответа от Google Функция ОбновитьФайл(Знач Токен, Знач Идентификатор, Знач Файл, Знач НовоеИмя = "") Экспорт OPI_ПреобразованиеТипов.ПолучитьСтроку(Токен); OPI_ПреобразованиеТипов.ПолучитьСтроку(Идентификатор); OPI_ПреобразованиеТипов.ПолучитьСтроку(НовоеИмя); OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(Файл); Если ЗначениеЗаполнено(НовоеИмя) Тогда Описание = Новый Соответствие; Описание.Вставить("Имя", НовоеИмя); Иначе Описание = ""; КонецЕсли; Возврат УправлениеФайлом(Токен, Файл, Описание, Идентификатор); КонецФункции // Удалить объект // Удаляет файл или каталог по ID // // Параметры: // Токен - Строка - Токен - token // Идентификатор - Строка - Идентификатор объекта для удаления - object // // Возвращаемое значение: // Соответствие Из КлючИЗначение - сериализованный JSON ответа от Google Функция УдалитьОбъект(Знач Токен, Знач Идентификатор) Экспорт OPI_ПреобразованиеТипов.ПолучитьСтроку(Токен); OPI_ПреобразованиеТипов.ПолучитьСтроку(Идентификатор); Заголовки = OPI_GoogleWorkspace.ПолучитьЗаголовокАвторизации(Токен); URL = "https://www.googleapis.com/drive/v3/files/" + Идентификатор; Ответ = OPI_Инструменты.Delete(URL, , Заголовки); Возврат Ответ; КонецФункции // Получить описание файла !NOCLI // // Возвращаемое значение: // Соответствие Из КлючИЗначение - Описание файла Функция ПолучитьОписаниеФайла() Экспорт Описание = Новый Соответствие; Описание.Вставить("MIME" , "image/jpeg"); // MIME-тип загружаемого файла Описание.Вставить("Имя" , "Новый файл.jpg"); // Имя файла с расширением Описание.Вставить("Описание" , "Это новый файл"); // Описание файла Описание.Вставить("Родитель" , "root"); // ID каталога загрузки или "root" для загрузки в корень Возврат Описание; КонецФункции #КонецОбласти #Область РаботаСКомментариями // Создать комментарий // Создает комментарий к файлу или каталогу // // Параметры: // Токен - Строка - Токен - token // Идентификатор - Строка - Идентификатор объекта, для которого необходим комментарий - object // Комментарий - Строка - Текст комментария - text // // Возвращаемое значение: // Соответствие Из КлючИЗначение - сериализованный JSON ответа от Google Функция СоздатьКомментарий(Знач Токен, Знач Идентификатор, Знач Комментарий) Экспорт OPI_ПреобразованиеТипов.ПолучитьСтроку(Токен); OPI_ПреобразованиеТипов.ПолучитьСтроку(Идентификатор); OPI_ПреобразованиеТипов.ПолучитьСтроку(Комментарий); Заголовки = OPI_GoogleWorkspace.ПолучитьЗаголовокАвторизации(Токен); URL = "https://www.googleapis.com/drive/v3/files/" + Идентификатор + "/comments?fields=*"; Параметры = Новый Структура; Параметры.Вставить("content", Комментарий); Ответ = OPI_Инструменты.POST(URL, Параметры, Заголовки); Возврат Ответ; КонецФункции // Получить комментарий // Получает комментарий по ID // // Параметры: // Токен - Строка - Токен - token // ИДОбъекта - Строка - Идентификатор файла или каталога размещения комментария - object // ИДКомментария - Строка - Идентификатор комментария - comment // // Возвращаемое значение: // Соответствие Из КлючИЗначение - сериализованный JSON ответа от Google Функция ПолучитьКомментарий(Знач Токен, Знач ИДОбъекта, Знач ИДКомментария) Экспорт OPI_ПреобразованиеТипов.ПолучитьСтроку(Токен); OPI_ПреобразованиеТипов.ПолучитьСтроку(ИДОбъекта); OPI_ПреобразованиеТипов.ПолучитьСтроку(ИДКомментария); Заголовки = OPI_GoogleWorkspace.ПолучитьЗаголовокАвторизации(Токен); URL = "https://www.googleapis.com/drive/v3/files/" + ИДОбъекта + "/comments/" + ИДКомментария; Параметры = Новый Структура; Параметры.Вставить("fields", "*"); Ответ = OPI_Инструменты.Get(URL, Параметры, Заголовки); Возврат Ответ; КонецФункции // Получить список комментариев // Получает список всех комментариев объекта // // Параметры: // Токен - Строка - Токен - token // ИДОбъекта - Строка - Идентификатор объекта - object // // Возвращаемое значение: // Соответствие Из КлючИЗначение - сериализованный JSON ответа от Google Функция ПолучитьСписокКомментариев(Знач Токен, Знач ИДОбъекта) Экспорт OPI_ПреобразованиеТипов.ПолучитьСтроку(Токен); OPI_ПреобразованиеТипов.ПолучитьСтроку(ИДОбъекта); Заголовки = OPI_GoogleWorkspace.ПолучитьЗаголовокАвторизации(Токен); URL = "https://www.googleapis.com/drive/v3/files/" + ИДОбъекта + "/comments"; Параметры = Новый Структура; Параметры.Вставить("fields", "*"); Ответ = OPI_Инструменты.Get(URL, Параметры, Заголовки); Возврат Ответ; КонецФункции // Удалить комментарий // Удаляет комментарий по ID // // Параметры: // Токен - Строка - Токен - token // ИДОбъекта - Строка - Идентификатор файла или каталога размещения комментария - object // ИДКомментария - Строка - Идентификатор комментария - comment // // Возвращаемое значение: // Соответствие Из КлючИЗначение - сериализованный JSON ответа от Google Функция УдалитьКомментарий(Знач Токен, Знач ИДОбъекта, Знач ИДКомментария) Экспорт OPI_ПреобразованиеТипов.ПолучитьСтроку(Токен); OPI_ПреобразованиеТипов.ПолучитьСтроку(ИДОбъекта); OPI_ПреобразованиеТипов.ПолучитьСтроку(ИДКомментария); Заголовки = OPI_GoogleWorkspace.ПолучитьЗаголовокАвторизации(Токен); URL = "https://www.googleapis.com/drive/v3/files/" + ИДОбъекта + "/comments/" + ИДКомментария; Ответ = OPI_Инструменты.Delete(URL, , Заголовки); Возврат Ответ; КонецФункции #КонецОбласти #КонецОбласти #Область СлужебныеПроцедурыИФункции Процедура ПолучитьСписокОбъектовРекурсивно(Знач Заголовки, МассивОбъектов, Подробно = Ложь, Отбор = "", Страница = "") URL = "https://www.googleapis.com/drive/v3/files"; Files = "files"; NPT = "nextPageToken"; Параметры = Новый Структура; Параметры.Вставить("fields", "*"); Если ЗначениеЗаполнено(Страница) Тогда Параметры.Вставить("pageToken", Страница); КонецЕсли; Если ЗначениеЗаполнено(Отбор) И ТипЗнч(Отбор) = Тип("Массив") Тогда ОтборСтрока = СтрСоединить(Отбор, " and "); Параметры.Вставить("q", ОтборСтрока); КонецЕсли; Результат = OPI_Инструменты.Get(URL, Параметры, Заголовки); Объекты = Результат[Files]; Страница = Результат[NPT]; Для Каждого ТекущийОбъект Из Объекты Цикл МассивОбъектов.Добавить(ТекущийОбъект); КонецЦикла; Если Объекты.Количество() > 0 И ЗначениеЗаполнено(Страница) Тогда ПолучитьСписокОбъектовРекурсивно(Заголовки, МассивОбъектов, Подробно, Отбор, Страница); КонецЕсли; КонецПроцедуры Процедура РазложитьОбъектыПодробно(Знач Токен, МассивОбъектов) Для Каждого ТекущийОбъект Из МассивОбъектов Цикл МассивФайлов = Новый Массив; ТекущийИД = ТекущийОбъект["id"]; Результат = ПолучитьСписокФайлов(Токен, , ТекущийИД); Для Каждого Файл Из Результат Цикл МассивФайлов.Добавить(Файл); КонецЦикла; ТекущийОбъект.Вставить("files", МассивФайлов); КонецЦикла; КонецПроцедуры Процедура СформироватьПараметрыЗагрузкиФайла(Описание) СформированноеОписание = Новый Соответствие; OPI_Инструменты.УдалитьПустыеПоляКоллекции(Описание); СоответствиеПолей = Новый Соответствие; СоответствиеПолей.Вставить("MIME" , "mimeType"); СоответствиеПолей.Вставить("Имя" , "name"); СоответствиеПолей.Вставить("Описание" , "description"); СоответствиеПолей.Вставить("Родитель" , "parents"); СоответствиеПолей.Вставить("Расширение", "fileExtension"); Для Каждого Элемент Из Описание Цикл Если Элемент.Ключ = "Родитель" Тогда ТекущееЗначение = Новый Массив; ТекущееЗначение.Добавить(Элемент.Значение); Иначе ТекущееЗначение = Элемент.Значение; КонецЕсли; ИмяПоля = СоответствиеПолей.Получить(Элемент.Ключ); СформированноеОписание.Вставить(ИмяПоля, ТекущееЗначение); КонецЦикла; Описание = СформированноеОписание; КонецПроцедуры Функция УправлениеФайлом(Знач Токен, Знач Файл = "", Знач Описание = "", Знач Идентификатор = "") OPI_ПреобразованиеТипов.ПолучитьСтроку(Токен); OPI_ПреобразованиеТипов.ПолучитьСтроку(Идентификатор); Если ЗначениеЗаполнено(Описание) Тогда OPI_ПреобразованиеТипов.ПолучитьКоллекцию(Описание); КонецЕсли; MimeType = "mimeType"; Если ЗначениеЗаполнено(Идентификатор) Тогда MIME = ПолучитьИнформациюОбОбъекте(Токен, Идентификатор)[MimeType]; Иначе MIME = Описание["MIME"]; КонецЕсли; Если Не ЗначениеЗаполнено(Описание) Тогда Описание = Новый Соответствие; КонецЕсли; Заголовки = OPI_GoogleWorkspace.ПолучитьЗаголовокАвторизации(Токен); СформироватьПараметрыЗагрузкиФайла(Описание); ОписаниеJSON = OPI_Инструменты.JSONСтрокой(Описание); СоответствиеФайла = Новый Соответствие; Если ЗначениеЗаполнено(Файл) Тогда OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(Файл); СоответствиеФайла.Вставить(Файл, MIME); Размер = Файл.Размер(); РазмерЧасти = 536870912; Если Размер < РазмерЧасти * 2 Тогда Ответ = ЗагрузитьМалыйФайл(ОписаниеJSON, СоответствиеФайла, Заголовки, Идентификатор); Иначе Ответ = ЗагрузитьБольшойФайл(Описание, СоответствиеФайла, Заголовки, Идентификатор); КонецЕсли; Иначе Ответ = ЗагрузитьМалыйФайл(ОписаниеJSON, СоответствиеФайла, Заголовки, Идентификатор); КонецЕсли; Возврат Ответ; КонецФункции Функция ЗагрузитьМалыйФайл(Знач Описание, Знач СоответствиеФайла, Знач Заголовки, Знач Идентификатор = "") URL = "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"; Если ЗначениеЗаполнено(Идентификатор) Тогда URL = СтрЗаменить(URL, "/files", "/files/" + Идентификатор); Ответ = OPI_Инструменты.PatchMultipartRelated(URL, Описание, СоответствиеФайла, Заголовки); Иначе Ответ = OPI_Инструменты.PostMultipartRelated(URL, Описание, СоответствиеФайла, Заголовки); КонецЕсли; Возврат Ответ; КонецФункции Функция ЗагрузитьБольшойФайл(Знач Описание, Знач СоответствиеФайла, Знач Заголовки, Знач Идентификатор = "") Для Каждого Файл Из СоответствиеФайла Цикл Двоичные = Файл.Ключ; Прервать; КонецЦикла; РазмерЧасти = 536870912; URL = "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable"; Ответ = OPI_Инструменты.Post(URL, Описание, Заголовки, Истина, Истина); АдресЗагрузки = Ответ.Заголовки["Location"]; Если Не ЗначениеЗаполнено(АдресЗагрузки) Тогда Возврат Ответ; КонецЕсли; Поток = Двоичные.ОткрытьПотокДляЧтения(); ЧтениеДанных = Новый ЧтениеДанных(Поток); ТекущаяПозиция = 0; ОбщийРазмер = Поток.Размер(); СтрОбщийРазмер = OPI_Инструменты.ЧислоВСтроку(ОбщийРазмер); Пока Поток.ТекущаяПозиция() < ОбщийРазмер - 1 Цикл Поток.Перейти(ТекущаяПозиция, ПозицияВПотоке.Начало); Результат = ЧтениеДанных.Прочитать(РазмерЧасти); ТекущиеДанные = Результат.ПолучитьДвоичныеДанные(); РазмерТекущих = ТекущиеДанные.Размер(); СледующаяПозиция = ТекущаяПозиция + РазмерТекущих - 1; Если Не ЗначениеЗаполнено(ТекущиеДанные) Тогда Прервать; КонецЕсли; ЗаголовокПотока = "bytes " + OPI_Инструменты.ЧислоВСтроку(ТекущаяПозиция) + "-" + OPI_Инструменты.ЧислоВСтроку(СледующаяПозиция) + "/" + СтрОбщийРазмер; ДопЗаголовки = Новый Соответствие; ДопЗаголовки.Вставить("Content-Length", OPI_Инструменты.ЧислоВСтроку(РазмерТекущих)); ДопЗаголовки.Вставить("Content-Range" , ЗаголовокПотока); ДопЗаголовки.Вставить("Content-Type" , "application/octet-stream"); Ответ = OPI_Инструменты.Put(АдресЗагрузки, ТекущиеДанные, ДопЗаголовки, Ложь, Истина); Если Ответ.КодСостояния >= 400 И Ответ.КодСостояния < 600 Тогда ЗаголовокПотока = "bytes */" + СтрОбщийРазмер; ДопЗаголовки.Вставить("Content-Range" , ЗаголовокПотока); ОтветПроверки = OPI_Инструменты.Put(АдресЗагрузки, "", ДопЗаголовки, Ложь, Истина); Если ОтветПроверки.КодСостояния >= 200 И ОтветПроверки.КодСостояния < 300 Тогда Возврат ОтветПроверки; ИначеЕсли ОтветПроверки.КодСостояния = 308 Тогда ЗагруженныеДанные = Ответ.Заголовки["Range"]; Иначе Возврат Ответ; КонецЕсли; Иначе ЗагруженныеДанные = Ответ.Заголовки["Range"]; КонецЕсли; Если Не ЗначениеЗаполнено(ЗагруженныеДанные) Тогда Возврат Ответ; КонецЕсли; ЗагруженныеДанные = СтрЗаменить(ЗагруженныеДанные, "bytes=", ""); МассивИнформации = СтрРазделить(ЗагруженныеДанные, "-", Ложь); Если Не МассивИнформации.Количество() = 2 Тогда Возврат Ответ; КонецЕсли; ТекущаяПозиция = Число(МассивИнформации[1]) + 1; СтрТекущаяПозиция = OPI_Инструменты.ЧислоВСтроку(ТекущаяПозиция); Процент = Строка(Цел(ТекущаяПозиция / ОбщийРазмер) * 100); Сообщить(СтрТекущаяПозиция + "/" + СтрОбщийРазмер + " (" + Процент + ")"); КонецЦикла; Возврат Ответ; КонецФункции #КонецОбласти