Флибсута всё..
К сожалению пришла новость, что создатель сайта филибусты из-за тяжелой болезни скоро покинет наш мир. А вместе с ним и его детище. Очень жаль. Еще одна эпоха ушла, читал книги скачанные оттуда последние 10+ лет
К сожалению пришла новость, что создатель сайта филибусты из-за тяжелой болезни скоро покинет наш мир. А вместе с ним и его детище. Очень жаль. Еще одна эпоха ушла, читал книги скачанные оттуда последние 10+ лет
Задача: спарсить данные из таблицы, которая находится в файле формата docx средствами 1С
Решение: по сути своей файл формата docx является zip архивом, в котором находятся файлы формата xml и внешние ресурсы, типа картинок, стилей и т.п. Текстовое же содержимое находится непосредственно в файле document.xml. Его нужно лишь прочитать, найти в нём таблицу и распарсить данные.
Для начала загрузим файл на сервер, переименуем его в zip, и откроем его при помощи метода 1С «ЧтениеZipФайла», а найденный в архиве файл document.xml извлекем для дальнейшей обработки:
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 |
&НаКлиенте Процедура ВыбратьФайлыИСделатьХорошо(Команда) Режим = РежимДиалогаВыбораФайла.Открытие; ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(Режим); ДиалогОткрытияФайла.ПолноеИмяФайла = ""; Фильтр = НСтр("ru = 'Текст'; en = 'Text'")+ "(*.docx)|*.docx"; ДиалогОткрытияФайла.Фильтр = Фильтр; ДиалогОткрытияФайла.МножественныйВыбор = ложь; ДиалогОткрытияФайла.Заголовок = "Выберите файлы"; Если ДиалогОткрытияФайла.Выбрать() Тогда МассивФайлов = ДиалогОткрытияФайла.ВыбранныеФайлы; ФайлСМС=""; Для Каждого ИмяФайла Из МассивФайлов Цикл ФайлСМС=ИмяФайла; конеццикла; если ФайлСМС<>"" тогда АдресХранилищаФайла = ""; Состояние("Перемещаю файл на сервер"); ПоместитьФайл(АдресХранилищаФайла, ФайлСМС, , Ложь, ЭтаФорма.УникальныйИдентификатор); Состояние("Обрабатывается файл "+ФайлСМС); таблицы=ПреобразоватьФайлDocXВМассивТаблиц(АдресХранилищаФайла); иначе сообщить("Файл не выбран"); конецесли; конецесли; КонецПроцедуры &НаСервере Функция ПреобразоватьФайлDocXВМассивТаблиц(АдресХранилищаФайла) ТЗ=Новый ТаблицаЗначений(); ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресХранилищаФайла); ИмяВременногоФайлаСпр = ПолучитьИмяВременногоФайла("zip"); ДвоичныеДанные.Записать(ИмяВременногоФайлаСпр); Архив = Новый ЧтениеZipФайла(ИмяВременногоФайлаСпр); ИмяВременногоФайлаXML = ПолучитьИмяВременногоФайла("xml"); Для Каждого Элемент Из Архив.Элементы Цикл если Элемент.Имя="document.xml" тогда Архив.Извлечь(Элемент, КаталогВременныхФайлов(), РежимВосстановленияПутейФайловZIP.НеВосстанавливать); конецесли; Конеццикла; Архив.Закрыть(); .... |
Далее файл documnet.xml необходимо загрузить как XML и распарсить в структуру при помощи построителя DOM. После чего останется только найти таблицу по имени узла w:tbl и поместить содержимое в таблицу значений:
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 |
ФайлXML = Новый ЧтениеXML; ФайлXML.ОткрытьФайл(КаталогВременныхФайлов()+"document.xml"); ПостроительDOMXML=Новый ПостроительDOM; ДокументДом=ПостроительDOMXML.Прочитать(ФайлXML); ПрочитаноСтрок=0; для каждого document из ДокументДом.ДочерниеУзлы цикл для каждого body из document.ДочерниеУзлы цикл для каждого el из body.ДочерниеУзлы цикл если el.ИмяУзла="w:tbl" тогда для каждого tab_el из el.ДочерниеУзлы цикл если tab_el.ИмяУзла="w:tr" тогда если ПрочитаноСтрок=0 тогда ТЗ.Колонки.Добавить(УбратьНеОбрабатываемыеСимволы(tab_el.ДочерниеУзлы[1].ТекстовоеСодержимое)); ТЗ.Колонки.Добавить(УбратьНеОбрабатываемыеСимволы(tab_el.ДочерниеУзлы[2].ТекстовоеСодержимое)); ТЗ.Колонки.Добавить(УбратьНеОбрабатываемыеСимволы(tab_el.ДочерниеУзлы[3].ТекстовоеСодержимое)); ТЗ.Колонки.Добавить(УбратьНеОбрабатываемыеСимволы(tab_el.ДочерниеУзлы[4].ТекстовоеСодержимое)); ТЗ.Колонки.Добавить(УбратьНеОбрабатываемыеСимволы(tab_el.ДочерниеУзлы[5].ТекстовоеСодержимое)); ТЗ.Колонки.Добавить(УбратьНеОбрабатываемыеСимволы(tab_el.ДочерниеУзлы[6].ТекстовоеСодержимое)); ТЗ.Колонки.Добавить(УбратьНеОбрабатываемыеСимволы(tab_el.ДочерниеУзлы[7].ТекстовоеСодержимое)); ТЗ.Колонки.Добавить(УбратьНеОбрабатываемыеСимволы(tab_el.ДочерниеУзлы[8].ТекстовоеСодержимое)); иначе если tab_el.ДочерниеУзлы[1].ТекстовоеСодержимое="Всего:" тогда прервать; КонецЕсли; если tab_el.ДочерниеУзлы[1].ТекстовоеСодержимое<>"1" тогда если tab_el.ДочерниеУзлы[6].ТекстовоеСодержимое<>"" тогда нс=ТЗ.Добавить(); нс[0]=tab_el.ДочерниеУзлы[1].ТекстовоеСодержимое; нс[1]=tab_el.ДочерниеУзлы[2].ТекстовоеСодержимое; нс[2]=tab_el.ДочерниеУзлы[3].ТекстовоеСодержимое; нс[3]=tab_el.ДочерниеУзлы[4].ТекстовоеСодержимое; нс[4]=tab_el.ДочерниеУзлы[5].ТекстовоеСодержимое; нс[4]=СтрЗаменить(нс[4],",","."); нс[4]=СтрЗаменить(нс[4]," ",""); если нс[4]="" тогда нс[4]="0";конецесли; нс[4]=Число(Формат(нс[4],"ЧГ=0")); нс[5]=tab_el.ДочерниеУзлы[6].ТекстовоеСодержимое; нс[6]=tab_el.ДочерниеУзлы[7].ТекстовоеСодержимое; нс[7]=tab_el.ДочерниеУзлы[8].ТекстовоеСодержимое; нс[7]=СтрЗаменить(нс[7],",","."); нс[7]=СтрЗаменить(нс[7]," ",""); если нс[7]="" тогда нс[7]="0";конецесли; нс[7]=Число(Формат(нс[7],"ЧГ=0")); конецесли; конецесли; конецесли; ПрочитаноСтрок=ПрочитаноСтрок+1; конецесли; конеццикла; если ПрочитаноСтрок>0 тогда прервать;конецесли; конецесли; если ПрочитаноСтрок>0 тогда прервать;конецесли; конеццикла; если ПрочитаноСтрок>0 тогда прервать;конецесли; конеццикла; если ПрочитаноСтрок>0 тогда прервать;конецесли; конеццикла; ФайлXML.Закрыть(); Возврат ТЗ; |
Предложило мне тут приложение HH оставить отзывы о работодателях, у которых пришлось в своё время поработать. Попытался оставить. Как итог: положительные отзывы публикуются моментально. Отрицательные — вот уже пару недель пытаюсь опубликовать, и все не проходят модерацию. Но я упорный. всё время меняю формулировки.. надеюсь кому то из модераторов надоест уже это и нажмут кнопку «пропустить».
P.S. Ну собственно это и ожидаемо, полистал несколько «работодателей» — плохих отзывов нет. Хотя точно знаю, что компания шлак.
Как то упустил эту возможность платформы 1С и никогда ранее не использовал. А тут вдруг прилетела задача поработать файлами большого размера (xlsx, csv), на основании данных в которых нужно строить различного вида отчёты. Пришла мысль: а почему бы не загрузить данные этих файлов в БД, а затем уже спокойно стоить на основании этих данных отчёты. Какие-то регистры, справочники и т.п. создавать в конфигурации для этого посчитал излишним. Самое правильное, подумал я, хранить всё вообще в какой-то сторонней базе (в моём случае в PostgreSQL). А 1С использовать только для вывода и формирования отчётов. Вот тут то я и вспомнил, что когда то мельком читал про «внешние источники данных» в 1С. Значит пришло время попробовать хранение информации во внешних источниках данных.
Сначала создам БД, с таблицами ls и shemes со структурой вида::
, где id — автоинкримент типа integer. Забегая вперед, следует отметить, что 1С не умеет при добавлении данных во внешние источники данных, передавать инкрементальное значение, а потому создадим триггер, который будет выполнятся перед транзакцией запроса INSERT, и заменяет значение id, на следующее по порядку:
Подготовка закончена. Теперь подготовим платформу 1С. А именно необходимо установить драйвер ODBC. Под Linux ставим из репозитария, под Windows скачиваем и устанавливаем отсюда: https://www.postgresql.org/ftp/odbc/releases/REL-16_00_0005-mimalloc/
Далее необходимо зайти в конфигуратор 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 |
// добвление новыелс=внешниеисточникиданных.ОтчетыДля1С.Таблицы.reports_1c_public_ls.СоздатьОбъект(); новыелс.name="4232344"; новыелс.Записать(); // изменение мХарактеристика = внешниеисточникиданных.ОтчетыДля1С.Таблицы.reports_1c_public_ls.НайтиПоПолю("id",3); мОбъект = мХарактеристика.ПолучитьОбъект(); мОбъект.name = "Уря! Чебуршка родил слона!"; мОбъект.Записать(); //удаление мХарактеристика = внешниеисточникиданных.ОтчетыДля1С.Таблицы.reports_1c_public_ls.НайтиПоПолю("id",3); мОбъект = мХарактеристика.ПолучитьОбъект(); мОбъект.Удалить(); // чтение Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | reports_1c_public_ls.id КАК id, | reports_1c_public_ls.name КАК name, | reports_1c_public_shemes.name КАК name1 |ИЗ | ВнешнийИсточникДанных.ОтчетыДля1С.Таблица.reports_1c_public_ls КАК reports_1c_public_ls | ЛЕВОЕ СОЕДИНЕНИЕ ВнешнийИсточникДанных.ОтчетыДля1С.Таблица.reports_1c_public_shemes КАК reports_1c_public_shemes | ПО reports_1c_public_ls.sheme = reports_1c_public_shemes.id"; РезультатЗапроса = Запрос.Выполнить(); ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать(); Пока ВыборкаДетальныеЗаписи.Следующий() Цикл сообщить(ВыборкаДетальныеЗаписи.name); сообщить(ВыборкаДетальныеЗаписи.name1); КонецЦикла; |
Задача: на нескольких серверах ограничить доступ к сайту по протоколу http/https для всех, кроме избранных IP.
Решить можно несколькими способами:
Мне предпочтительней было сделать это на уровне файревола, т.к. таким образом не нужно прописывать запрет на доступ на каждом сайте, а запрещаю на ВСЕХ сайтах размещенных на этом сервере одновременно.
Принцип прописывания правил для всех файреволов одинаков: запрещаем по умолчанию всё, кроме того что нужно. Так как у меня немного зоопарк по серверам, то два различных файревола.
Ubuntu и иже с ним:
1 2 3 4 5 6 |
ufw default deny outgoing ufw default deny incoming ufw allow out 53 ufw allow from 19.82.24.12 to any port 443 ufw allow from 19.82.34.12 to any port 80 service ufw restart |
CentOS и иже с ним:
1 2 3 4 5 |
firewall-cmd --zone=public --remove-service=http firewall-cmd --zone=public --remove-service=https firewall-cmd --permanent --add-rich-rule 'rule family="ipv4" source address="15.8.15.1" port port="443" protocol="tcp" accept' firewall-cmd --permanent --add-rich-rule 'rule family="ipv4" source address="15.8.15.1" port port="80" protocol="tcp" accept' systemctl restart firewalld.service |