1C 7.7 краткая шпаргалка

Давненько не трогал 7.7 вообще. Да так, что когда пришлось, понял что забыл практически всё. Итак краткая шпаргалка для тех кто вынужден был сделать временный «даунгрейд» 😉

  1. Поиск процедур/функций в коде конфигурации осуществляется через меню «Конфигурация->Поиск во всех текстах»
  2. Запросы можно писать через конструктор «Конструкторы->Запрос», при этом он разместится в позиции курсора, а далее его можно редактировать будет при запуске конструктора по имени
  3. Обход запроса осуществляется по уровням группировки
	Запрос = СоздатьОбъект("Запрос");
	ТекстЗапроса = 
	"//{{ЗАПРОС(Сформировать)
	|Обрабатывать НеПомеченныеНаУдаление;
	|ПокДн = Справочник.ПоказанияСчетчиков.ПокДн;
	|Владелец = Справочник.ПоказанияСчетчиков.Владелец;
	|ТекущийЭлемент = Справочник.ПоказанияСчетчиков.ТекущийЭлемент;
	|Код = Справочник.ПоказанияСчетчиков.Код;
	|Группировка ТекущийЭлемент Упорядочить по ТекущийЭлемент.Код;	
	|Условие(Владелец = счтк);
	|"//}}ЗАПРОС
	;
	// Если ошибка в запросе, то выход из процедуры
	Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
		возврат 0;
	КонецЕсли;	
	Пока Запрос.Группировка(1,сортировка) = 1 Цикл        
		Дата_Показания="";	
		если сортировка=-1 тогда
			Дата_Показания=НормализоватьДату(Запрос.Код);
		конецесли;
	    возврат Запрос.ПокДн;
	КонецЦикла;
	
	возврат 0;

4. Отличия в «макете» в 7.7 от 8.х: Вместо «Макет» — «Таблица», вместо «Имя» — «Секция»

5. Данные в «Тело» можно заносить например так:

	Таб = СоздатьОбъект("Таблица");
	Таб.ИсходнаяТаблица("Расчеты");
	Таб.ВывестиСекцию("Шапка");


	МассивСальдо.ВыбратьСтроки();
	Пока МассивСальдо.ПолучитьСтроку() = 1 Цикл
	   // Сообщить(Шаблон("[тз.НомерСтроки]. [тз.Товар] х [тз.Количество] ед."));
	   лс=МассивСальдо.ЛС;	   
	   начало=МассивСальдо.СальдоНачало;
	   
	   начхол=МассивСальдо.ХолоднаяВода;
	   начот=МассивСальдо.Отопление;
	   начкан=МассивСальдо.Канализация;
	   
	   сто=начхол+начот+начкан; 
	   если сто=0 тогда сто=1;конецесли;
	   начхол_пр=100*начхол/сто;
	   начот_пр=100*начот/сто;
	   начкан_пр=100*начкан/сто;
	   
	   оплачено=МассивСальдо.Оплачено;
	   конец=МассивСальдо.СальдоНачало+МассивСальдо.ХолоднаяВода+МассивСальдо.Отопление+МассивСальдо.Канализация-МассивСальдо.Оплачено;
	   
	   распхол=окр(начхол_пр*конец/100,2);
	   распротоп=окр(начот_пр*конец/100,2);
	   раскан=окр(начкан_пр*конец/100,2);
	   Таб.ВывестиСекцию("Тушка");																			
	КонецЦикла;

	
	Таб.Опции(0,0,0,0);
	Таб.ТолькоПросмотр(1);
	Таб.Показать("Результат",);

6. Если реквизит периодический, то данные из него можно получить:

норматив=ЖилоеЗдание.ВидТарифаХВиКан.НормативГВ.Получить(РабочаяДата());

7. Упоротый тип boolean: Да=Истина,Нет=Ложь

Ротация логов в приложении на Python

Задача: в приложении используется встроенный logging. Необходимо организовать ротацию логов со сжатием «архива»

Решение:

import coloredlogs,logging
from logging.handlers import TimedRotatingFileHandler
import gzip

class GZipRotator:
    def __call__(self, source, dest):
        os.rename(source, dest)
        f_in = open(dest, 'rb')
        f_out = gzip.open("%s.gz" % dest, 'wb')
        f_out.writelines(f_in)
        f_out.close()
        f_in.close()
        os.remove(dest)

rotation_logging_handler = TimedRotatingFileHandler(gconfig["logging_file"], when='D', interval=1, backupCount=5)
rotation_logging_handler.rotator=GZipRotator();
fh = logging.FileHandler('spam.log')
fh.filemode="a"

logger = logging.getLogger(__name__)
logging.basicConfig(format='%(asctime)s %(message)s',datefmt='%d.%m.%Y %H:%M:%S',level=gconfig["logging_level"],handlers=[rotation_logging_handler,fh])
logging.captureWarnings(True)

Результатом работы будет создание 1 раз в день сжатого файла

pgsql: функция генерации пароля

Задача: сбросить у всех пользователей пароль

Решение: воспользуемся функцией генерации пароля:

DECLARE
   vPassword text;
   chars text;
BEGIN
   vPassword := ''; 
   chars := 
'@#$%*abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  WHILE((select COALESCE(substring(vPassword from '.*[a-z]+.*'),'')) = '' OR (select COALESCE(substring(vPassword from '.*[A-Z]+.*'),'')) = '' OR (select COALESCE(substring(vPassword from '.*[0-9]+.*'),'')) = '') LOOP
  vPassword := '';
   FOR i IN 1..12 LOOP
     vPassword := vPassword || SUBSTRING(chars, ceil(random()*LENGTH(chars))::integer, 1);
  END LOOP;
   END LOOP;
   return vPassword;
END;

Доступ к другой БД 1С через V83.COMConnector

Задача: перенести содержимое регистра из одной БД в другую.

Решение: одним из способов (помимо обработки ВыгрузкаЗагрузкаДанныхXML.epf) является прямая загрузка через COM подключение. Вышло примерно так:

// соединяемся с БД	
		V8=Новый COMОбъект("V83.COMConnector");
		Попытка
			База=V8.Connect("Srvr=""fserferfw""; Ref=""ewrfwe""; Usr=""werfwerfwe""; Pwd=""werfwerfwer"";")
		Исключение
			сообщить("Чтото пошло не так..");
		КонецПопытки;
	
	// делаем выборку из нашего регистра
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ ПЕРВЫЕ 10
		|	ОчередьРаботыСВотцапСрезПоследних.Телефон КАК Телефон,
		|	ОчередьРаботыСВотцапСрезПоследних.ЛицевойСчет КАК ЛицевойСчет,
		|	ОчередьРаботыСВотцапСрезПоследних.ЛицевойСчет.Код КАК ЛицевойСчетКод,
		|	ОчередьРаботыСВотцапСрезПоследних.Период КАК Период,
		|	ОчередьРаботыСВотцапСрезПоследних.Сообщение КАК Сообщение,
		|	ОчередьРаботыСВотцапСрезПоследних.ДатаОбработки КАК ДатаОбработки
		|ИЗ
		|	РегистрСведений.ОчередьРаботыСВотцап.СрезПоследних КАК ОчередьРаботыСВотцапСрезПоследних
		|ГДЕ
		|	ОчередьРаботыСВотцапСрезПоследних.Результат = &Результат";	
	Запрос.УстановитьПараметр("Результат", перечисления.ГринРезультатЗапроса.Успешно);	
	РезультатЗапроса = Запрос.Выполнить();	
	ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();	
	Пока ВыборкаДетальныеЗаписи.Следующий() Цикл							
			МенеджерЗаписи =База.РегистрыСведений.ОчередьРаботыСВотцап.СоздатьМенеджерЗаписи();			
			МенеджерЗаписи.ЛицевойСчет = База.справочники.vscЛицевыеСчета.НайтиПоКоду(ВыборкаДетальныеЗаписи.ЛицевойСчетКод);
			МенеджерЗаписи.Телефон = ВыборкаДетальныеЗаписи.Телефон;
			МенеджерЗаписи.Действие =  База.перечисления.ГринДействияСВотцап.ПроверкаНаличияВотцап;
			МенеджерЗаписи.Результат=  База.перечисления.ГринРезультатЗапроса.Успешно;
			МенеджерЗаписи.ДатаОбработки=ВыборкаДетальныеЗаписи.ДатаОбработки;
			МенеджерЗаписи.Период=ВыборкаДетальныеЗаписи.Период;
			МенеджерЗаписи.Статус= База.перечисления.СтатусОчередиВотцап.Обработан;
			МенеджерЗаписи.Записать();  		
		
	КонецЦикла;

Python: из объекта в JSON

Если применять json.dumps с объектом, то можно словить ошибку сериализации объекта. Для обхода этого можно применить следующий способ:

def serialize(obj):    
    return obj.__dict__
loc=json.dumps(loc, default=serialize)

В этом случае, если штатный сериализатор «не справляется», то ему будет передана «подсказка» о типе

1 61 62 63 64 65 300