Во время реализации соответствующей задачи в 1С иногда возникает потребность где-то временно хранить табличные данные, помимо самой конфигурации.
Это может быть удобным для следующих случаев:
- Для хранения каких-либо настроек у отчётов или обработок;
- Для тестирования или ведения логов (для временного хранения результата) при выполнении кода или запроса в 1С;
- Для загрузки/выгрузки данных между информационными базами 1С.
Во многих случаях очень удобно всегда иметь под рукой кнопки «Выгрузить таблицу» и «Загрузить таблицу», чтобы, к примеру, не заполнять вручную табличную часть документов или обработок.
Алгоритм
Порядок программных действий при выгрузке в файл выглядит так:
- Подготавливаем таблицу значений (выгружаем из табличной части, выбираем колонки);
- Конвертируем таблицу значений в табличный документ;
- Сохраняем табличный документ в MXL.
При загрузке таблицы порядок действий такой:
- Читаем из файла табличный документ;
- Конвертируем табличный документ в таблицу значений;
- Используем эту таблицу значений в своих целях (загружаем в табличную часть).
Соответственно файл для хранения данных таблицы имеет расширение *.mxl.
Функции и процедуры
Основные функции для реализации поставленной задачи следующие:
- ПреобразоватьТДвТЗ – Функция преобразования табличного документа в таблицу значений.
- ПреобразоватьТЗвТД – Функция обратного преобразования таблицы значений в табличный документ.
- ПрочитатьТЗИзMXL – Читает из файла данные, определяет колонки таблицы и преобразует эти данные в таблицу значений.
- ЗаписатьТЗВMXL – Преобразует таблицу значений в табличный документ и записывает его в файл.
Пример реализации
Ниже можно скачать обработку с примером реализации данного алгоритма.
Обработка имеет 3 функциональных кнопки:
- Выгрузить
- Загрузить
- Очистить.
Приведём здесь код 1С для всех вышеописанных функций:
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 53 54 55 56 57 58 59 60 61 62 63 64 | // Преобразовать табличный документ в таблицу значений. // // Параметры: // ТабДок - <ТабличныйДокумент> - Исходный табличный документ; // СтруктураКолонок - <Структура>, <ТаблицаЗначений> - Структура колонок; // НачалоСтрока - <Число> - Строка начала области; // НачалоСтолбец - <Число> - Столбец начала области; // КонецСтрока - <Число> - Строка конца области; // КонецСтолбец - <Число> - Столбец конца области. // // Возвращаемое значение: // <ТаблицаЗначений> - Полученная таблица значений. // Функция ПреобразоватьТДвТЗ(ТабДок, СтруктураКолонок, Знач НачалоСтрока = Неопределено, Знач НачалоСтолбец = Неопределено, Знач КонецСтрока = Неопределено, Знач КонецСтолбец = Неопределено) Экспорт // Определение габаритов таблицы Если НачалоСтрока = Неопределено И НачалоСтолбец = Неопределено Тогда НачалоСтрока = 1; НачалоСтолбец = 1; КонецЕсли; Если НачалоСтрока = Неопределено Тогда НачалоСтрока = 1; Пока НЕ ТабДок.Область(НачалоСтрока, НачалоСтолбец).СодержитЗначение И НачалоСтрока < ТабДок.ВысотаТаблицы Цикл НачалоСтрока = НачалоСтрока + 1; КонецЦикла; ИначеЕсли НачалоСтолбец = Неопределено Тогда НачалоСтолбец = 1; Пока НЕ ТабДок.Область(НачалоСтрока, НачалоСтолбец).СодержитЗначение И НачалоСтолбец < ТабДок.ШиринаТаблицы Цикл НачалоСтолбец = НачалоСтолбец + 1; КонецЦикла; КонецЕсли; КонецСтрока = ?(КонецСтрока = Неопределено, ТабДок.ВысотаТаблицы, КонецСтрока); КонецСтолбец = ?(КонецСтолбец = Неопределено, ТабДок.ШиринаТаблицы, КонецСтолбец); // Преобразование ЭтоТаблица = (ТипЗнч(СтруктураКолонок) = Тип("ТаблицаЗначений")); ТабЗначений = ПолучитьТаблицуВывода(СтруктураКолонок); Для ИндексСтроки = НачалоСтрока По КонецСтрока Цикл СтрокаТЗ = ТабЗначений.Добавить(); ИндексКолонки = НачалоСтолбец; Для Каждого Колонка Из СтруктураКолонок Цикл НаименованиеКолонки = ?(ЭтоТаблица, Колонка.Наименование, Колонка.Ключ); пИндексКолонки = ?(ЭтоТаблица, Колонка.СтолбецОтчёт, ИндексКолонки); Если ТабДок.Область(ИндексСтроки, пИндексКолонки).СодержитЗначение Тогда СтрокаТЗ[НаименованиеКолонки] = ТабДок.Область(ИндексСтроки, пИндексКолонки).Значение; Иначе СтрокаТЗ[НаименованиеКолонки] = ТабДок.Область(ИндексСтроки, пИндексКолонки).Текст; КонецЕсли; ИндексКолонки = ИндексКолонки + 1; КонецЦикла; КонецЦикла; Возврат ТабЗначений; КонецФункции; |
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 | // Преобразовать таблицу значений в табличный документ. // // Параметры: // ТабЗначений - <ТаблицаЗначений> - Исходная таблица значений; // ТабДок - <ТабличныйДокумент> - Полученный табличный документ. Если параметр не задан, // то документ создаётся заново и возвращается функцией; // НачалоСтрока - <Число> - Строка начала области; // НачалоСтолбец - <Число> - Столбец начала области; // ВыводитьЗаголовки - <Булево> - Определяет выводить ли имена колонок или нет. // // Возвращаемое значение: // <ТабличныйДокумент> - Полученный табличный документ (возвращает параметр "ТабДок"). // Функция ПреобразоватьТЗвТД(ТабЗначений, ТабДок = Неопределено, Знач НачалоСтрока = Неопределено, Знач НачалоСтолбец = Неопределено, ВыводитьЗаголовки = Ложь) Экспорт Если ТабДок = Неопределено Тогда ТабДок = Новый ТабличныйДокумент; КонецЕсли; // Определение габаритов таблицы НачалоСтрока = ?(НачалоСтрока = Неопределено, 1, НачалоСтрока); НачалоСтолбец = ?(НачалоСтолбец = Неопределено, 1, НачалоСтолбец); // Преобразование ИндексСтроки = НачалоСтрока; Если ВыводитьЗаголовки Тогда ИндексКолонки = НачалоСтолбец; Для Каждого Колонка Из ТабЗначений.Колонки Цикл ТабДок.Область(ИндексСтроки, ИндексКолонки).Текст = ?(ПустаяСтрока(Колонка.Заголовок), Колонка.Имя, Колонка.Заголовок); ИндексКолонки = ИндексКолонки + 1; КонецЦикла; ИндексСтроки = ИндексСтроки + 1; КонецЕсли; Для Каждого Элемент Из ТабЗначений Цикл ИндексКолонки = НачалоСтолбец; Для Каждого Колонка Из ТабЗначений.Колонки Цикл ТабДок.Область(ИндексСтроки, ИндексКолонки).СодержитЗначение = Истина; ТабДок.Область(ИндексСтроки, ИндексКолонки).ТипЗначения = Новый ОписаниеТипов(Колонка.ТипЗначения); ТабДок.Область(ИндексСтроки, ИндексКолонки).Значение = Элемент[Колонка.Имя]; ИндексКолонки = ИндексКолонки + 1; КонецЦикла; ИндексСтроки = ИндексСтроки + 1; КонецЦикла; Возврат ТабДок; КонецФункции; |
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 | // Читает табличный документ из файла MXL и преобразует его в таблицу значений. // // Параметры: // ИмяФайла - <Строка> - Путь к файлу MXL; // СтруктураКолонок - <Структура>, <ТаблицаЗначений> - Структура колонок. Если этот параметр // не задан, то структура колонок формируется из самого табличного документа; // ЕстьЗаголовок - <Булево> - Есть ли первая строка с заголовками или нет. // // Возвращаемое значение: // <ТаблицаЗначений> - Полученная таблица значений. // Функция ПрочитатьТЗИзMXL(ИмяФайла, СтруктураКолонок = Неопределено, ЕстьЗаголовок = Истина) Экспорт ТабДок = Новый ТабличныйДокумент; ТабДок.Прочитать(ИмяФайла); Если СтруктураКолонок = Неопределено И ЕстьЗаголовок Тогда СтруктураКолонок = Новый Структура; Для ИндексКолонки = 1 По ТабДок.ШиринаТаблицы Цикл Обл1 = ТабДок.Область(1, ИндексКолонки); Обл2 = ТабДок.Область(2, ИндексКолонки); ИмяКолонки = СокрЛП(Обл1.Текст); ИмяКолонки = ?(Найти(ИмяКолонки, " ") > 0, СтрЗаменить(ТРег(ИмяКолонки), " ", ""), ИмяКолонки); СтруктураКолонок.Вставить(ИмяКолонки, ?(Обл2.СодержитЗначение, Обл2.ТипЗначения, Новый ОписаниеТипов)); КонецЦикла; ИначеЕсли СтруктураКолонок = Неопределено И НЕ ЕстьЗаголовок Тогда СтруктураКолонок = Новый Структура; Для ИндексКолонки = 1 По ТабДок.ШиринаТаблицы Цикл Обл2 = ТабДок.Область(1, ИндексКолонки); ИмяКолонки = "К" + Формат(ИндексКолонки, "ЧДЦ=0; ЧН=0; ЧГ=0"); СтруктураКолонок.Вставить(ИмяКолонки, ?(Обл2.СодержитЗначение, Обл2.ТипЗначения, Новый ОписаниеТипов)); КонецЦикла; КонецЕсли; Таблица = ПреобразоватьТДвТЗ(ТабДок, СтруктураКолонок, ?(ЕстьЗаголовок, 2, 1), 1); Возврат Таблица; КонецФункции; |
1 2 3 4 5 6 7 8 9 10 11 12 13 | // Сохраняет таблицу значений в файле в виде табличного документа. // // Параметры: // ИмяФайла - <Строка> - Путь к файлу MXL; // ТабЗначений - <ТаблицаЗначений> - Сохраняемая таблица значений; // ЕстьЗаголовок - <Булево> - Есть ли первая строка с заголовками или нет. // Процедура ЗаписатьТЗВMXL(ИмяФайла, ТабЗначений, ЕстьЗаголовок = Истина) Экспорт ТабДок = ПреобразоватьТЗвТД(ТабЗначений, Неопределено, 1, 1, ЕстьЗаголовок); ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.MXL); КонецПроцедуры; |
Целиком скачайте обработку по ссылке ниже.
Смело используйте этот код 1С для реализации своих проектов! Если в коде имеются баги (ошибки), просьба сообщить об этом, написав в комментариях ниже.
И хорошо что так
Полезная статья. Спасибо. Только нет функции «ПолучитьТаблицуВывода», где создается таблица по структуре колонок:
ТабЗначений = ПолучитьТаблицуВывода(СтруктураКолонок);
может кому пригодится
// Разбирает строку в массив подстрок по разделителю.
// При этом пробелы между подстроками не учитываются.
//
// Параметры:
// Стр — исходная строка;
// СтрРазделитель — разделитель, по умолчанию «,»;
// ИгнорироватьПустые — игнорировать ли пустые места между разделителями.
//
// Возвращаемое значение:
// Массив строк
//
Функция РазобратьСтрокуВМассивПоРазделителю(Знач Стр, СтрРазделитель = «,», ИгнорироватьПустые = Ложь) Экспорт
Результат = Новый Массив;
ВхождениеРазделителя = Найти(Стр, СтрРазделитель);
Пока ВхождениеРазделителя 0 Цикл
ЧастьДоРазделителя = СокрЛП(Лев(Стр, ВхождениеРазделителя — 1));
Если НЕ (ИгнорироватьПустые И ПустаяСтрока(ЧастьДоРазделителя)) Тогда
Результат.Добавить(ЧастьДоРазделителя);
КонецЕсли;
Стр = СокрЛП(Сред(Стр, ВхождениеРазделителя + 1));
ВхождениеРазделителя = Найти(Стр, СтрРазделитель);
КонецЦикла;
Если НЕ (ИгнорироватьПустые И ПустаяСтрока(Стр)) Тогда
Результат.Добавить(СокрЛП(Стр));
КонецЕсли;
Возврат Результат;
КонецФункции
// Создаёт новую таблицу значений с заданными колонками.
//
// Параметры:
// пКолонки — , , , , —
// Набор колонок для таблицы значений.
//
// Возвращаемое значение:
// — Созданная таблица.
//
Функция ПолучитьТаблицуВывода(пКолонки) Экспорт
ТЗ = Новый ТаблицаЗначений;
Если пКолонки Неопределено Тогда
Если ТипЗнч(пКолонки) = Тип(«Строка») Тогда
пКолонки = РазобратьСтрокуВМассивПоРазделителю(пКолонки);
КонецЕсли;
Если ТипЗнч(пКолонки) = Тип(«Структура») Тогда
Для Каждого Поле Из пКолонки Цикл
СтрокаТабл = ТЗ.Колонки.Добавить(Поле.Ключ, Поле.Значение);
КонецЦикла;
ИначеЕсли ТипЗнч(пКолонки) = Тип(«СписокЗначений») Тогда
Для Каждого Поле Из пКолонки Цикл
Если Поле.Пометка Тогда
СтрокаТабл = ТЗ.Колонки.Добавить(Поле.Значение, пКолонки.ТипЗначения, Поле.Представление);
КонецЕсли;
КонецЦикла;
ИначеЕсли ТипЗнч(пКолонки) = Тип(«ТаблицаЗначений») Тогда
ЕстьНаименование = (пКолонки.Колонки.Найти(«Наименование») Неопределено);
ЕстьТипЗначения = (пКолонки.Колонки.Найти(«ТипЗначения») Неопределено);
ЕстьЗаголовок = (пКолонки.Колонки.Найти(«Заголовок») Неопределено);
ЕстьШирина = (пКолонки.Колонки.Найти(«Ширина») Неопределено);
Для Каждого Поле Из пКолонки Цикл
СтрокаТабл = ТЗ.Колонки.Добавить(?(ЕстьНаименование, Поле.Наименование, «»), ?(ЕстьТипЗначения, Поле.ТипЗначения, Новый ОписаниеТипов), ?(ЕстьЗаголовок, Поле.Заголовок, «»), ?(ЕстьШирина, Поле.Ширина, 0));
КонецЦикла;
Иначе
Для Каждого Поле Из пКолонки Цикл
СтрокаТабл = ТЗ.Колонки.Добавить(Поле);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат ТЗ;
КонецФункции