HH и отзывы о работодателе

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

P.S. Ну собственно это и ожидаемо, полистал несколько «работодателей» — плохих отзывов нет. Хотя точно знаю, что компания шлак.

1С: Хранение информации во внешних источниках данных

Как то упустил эту возможность платформы 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С.Таблицы.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);
	КонецЦикла;

Update 16/09/2025: таки автоувеличение идентификатора умеет. Достаточно его указать как «только чтение» в 1С:

Но можно и с триггерами мудрить для желающих 😉

Запрет доступа по протоколу https «для всех кроме»

Задача: на нескольких серверах ограничить доступ к сайту по протоколу http/https для всех, кроме избранных IP.

Решить можно несколькими способами:

  • поправить .htaccess, добавив в него deny from all и allow from IP
  • на уровне файревола

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

Принцип прописывания правил для всех файреволов одинаков: запрещаем по умолчанию всё, кроме того что нужно. Так как у меня немного зоопарк по серверам, то два различных файревола.

Ubuntu и иже с ним:

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 и иже с ним:

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

Создание файла формата DBF в 1С

Задача: создать силами платформы 1c файл в формате DBF (выгрузка в формате dbf)

Решение: собственно в 1С всё есть. Будем использовать метод XBase. При работе с DBF важно помнить, что это очень старый формат хранения данных, но тем не менее до сих пор используется для различного вида обменов. Его ограничениями являются:

  • длина имени файлов не более 8 символов, поэтому при генерации имени временного файла, не получится использовать функцию ПолучитьИмяВременногоФайла()
  • файл не должен быть больше 2ггб
  • имя колонки не может быть длиннее 10 символов
  • файл создается НЕ в кодировке UTF-8 (он в такую не умеет)
  • файл нужно сначала создать, потом закрыть, потом открыть и записать в него данные

А так, файл создаётся достаточно просто:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	объект.РезультирующиеДанные.Очистить();
		нс=объект.РезультирующиеДанные.Добавить();
		нс.Код_фиас="1112232423";
		нс.НомерКвартиры="43";
		нс.Задолженость="20";
		нс.Переплата="12";
		нс.Услуга="КТВ+Домофон";
		нс.ЛС_База="235465";
		нс.ЛС_ЕПД="223234234";
		нс.ЛС_Электрика="445457223";
		нс.Адрес="г. Вологда,ул Лёнина 3";
		нс.АдресДоставки="г. Сокол, ул Лёнина 4";	
КонецПроцедуры

&НаСервере
Функция ВыгрузитьDBFНаСервере()    
	answer=Новый Структура("хранилище,имяфайла");
	НоваяТаблица = Новый XBase;
    НоваяТаблица.Кодировка = КодировкаXBase.ANSI;
	
    НоваяТаблица.Поля.Добавить("fias","S",50);
	НоваяТаблица.Поля.Добавить("flat","S",10);
	НоваяТаблица.Поля.Добавить("credit","N",10,2);
	НоваяТаблица.Поля.Добавить("debet","N",10,2);
	НоваяТаблица.Поля.Добавить("service","S",50);
	НоваяТаблица.Поля.Добавить("ls_base","S",10);
	НоваяТаблица.Поля.Добавить("ls_epd","S",10);
	НоваяТаблица.Поля.Добавить("ls_electro","S",10);
	НоваяТаблица.Поля.Добавить("address","S",100);
	НоваяТаблица.Поля.Добавить("delivery","S",100);

	имя_фр_файла=Лев(Новый УникальныйИдентификатор(),8)+".dbf";
	ПутьКНовомуDBF = КаталогВременныхФайлов()+"/"+имя_фр_файла;
    НоваяТаблица.СоздатьФайл(ПутьКНовомуDBF); 
    НоваяТаблица.ЗакрытьФайл();	
	
	Таблица = Новый XBase;
    Таблица.ОткрытьФайл(ПутьКНовомуDBF,, Ложь);    	
	
	для каждого стр из объект.РезультирующиеДанные цикл
	   Таблица.Добавить();
 	   Таблица.fias = стр.Код_фиас;
 	   Таблица.credit = стр.НомерКвартиры;
	   Таблица.debet = стр.Задолженость;
	   Таблица.service = стр.Переплата;
	   Таблица.ls_base = стр.Услуга;
	   Таблица.ls_epd = стр.ЛС_База;
	   Таблица.ls_electro = стр.ЛС_ЕПД;
	   Таблица.address = стр.address;
	   Таблица.delivery = стр.АдресДоставки;
 	   Таблица.Записать(); 
	конеццикла;	
	
	Таблица.ЗакрытьФайл();
	
	Двоичное=Новый ДвоичныеДанные(ПутьКНовомуDBF);
	answer.хранилище=ПоместитьВоВременноеХранилище(Двоичное,ЭтаФорма.УникальныйИдентификатор);	
	answer.имяфайла=имя_фр_файла;
	
	возврат answer;	
КонецФункции

&НаКлиенте
Процедура ВыгрузитьDBF(Команда)
	рез=ВыгрузитьDBFНаСервере();
	
		Двоичное=ПолучитьИзВременногоХранилища(рез.хранилище);			
		ИмяФайла = КаталогВременныхФайлов() + рез.имяфайла;		
		Двоичное.Записать(ИмяФайла);
		ЗапуститьПриложение(ИмяФайла);	
КонецПроцедуры
выгрузка в формате dbf

1С: Формирование отчёта в обработке из макета

Несколько статей уже на моём сайте на эту тему есть вывод отчета из макета), но они слегка протухли за прошедшее время, и почему-то отображаются не вполне корректно. Потому повторю.

Сначала нужно создать макет:

вывод отчета из макета

Нарисуем структуру отчета, присвоим имена блокам, обозначим ячейки которые будут заполнятся параметрами.

Далее на клиенте на форму выведем кнопку, и на неё повесим на неё обработчик заполнения отчета и вывода его на экран:

&НаКлиенте
Процедура СформироватьОтчёт(Команда)
	ТабличныйДокумент = Новый ТабличныйДокумент;
	ТабличныйДокумент=ПечатнаяФормаНаСервере();
	ТабличныйДокумент.Показать();
КонецПроцедуры

Формирование и вывод отчета из макета:

&НаСервере
Функция ПечатнаяФормаНаСервере()	                                            
 ТабДок=Новый ТабличныйДокумент;	
 Макет=РеквизитФормыВЗначение("Объект").ПолучитьМакет("МакетУдовлетворённость");
 ОбластьШапка=Макет.ПолучитьОбласть("Шапка");
 ТабДок.Вывести(ОбластьШапка);
   Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
     ОбластьТушка=Макет.ПолучитьОбласть("тушка");
     ОбластьТушка.Параметры.ид=ВыборкаДетальныеЗаписи.ИдентификаторОпроса;
     ТабДок.Вывести(ОбластьТушка);
   КонецЦикла;	
...
возврат ТабДок;
КонецФункции
1 20 21 22 23 24 310