ZMore Марат

76
Рейтинг

Marik



  •   Регистрация: 06.05.2007 (16 лет назад)

  •   Был(а) на сайте: 25.04.2024

Подписчики 4

Группы

Профессиональный разработчик

Рейтинг 76

Быстрое сворачивание 1С 77 ТиС (от 10 до 40 минут) независимо от размера ИБ.

Инструменты и обработки Программист Оперативный учет 7.7 1С:Торговля и склад 7.7 Управленческий учет Windows Абонемент ($m) Конфигурация (md, cf) Свертка базы

Хотя большинство пользователей перешло на 1С 8ХХ, но есть еще очень много торговых организаций до сих пор эксплуатирующих 1С 77 ТиС. И пока еще не собираются переходить на новую платформу, а свертку делать надо. Есть много решений, я решил поделиться своим. Основное отличие: 1. Универсальность 2. Быстрота 3. Свертку можно делать на любую дату (не обязательно на начало года)

1 стартмани

15.11.2014    31706    121    Marik    27       

3

Комментарии

НовостиЗапускаем "Большой опрос 1С-сообщества от Инфостарт 2023"#485 02.12.23 8:24
Иногда помогает, но в последнее время все на сайте стало платным, практически нет ничего полезного из бесплатной категории.
ОбменВ продолжение темы: КД: Передача параметров из 7.7 в 8.x#1 19.04.20 20:23
Собственно в продолжение темы: "КД: Передача параметров из 7.7 в 8.x" INFOSTART.RU

Цитата

PPS. Спасибо Totoro за дополнение, есть еще один вариант передачи параметров. Иногда бывает необходимо передать параметр не для всей конвертации, а для отдельного объекта (или более того, нескольких объектов). Например, если у приемника нет реквизита для значения, а само значение нужно для выбора варианта заполнения объекта (см. счет учета в основных средствах в семерке и, скажем, в УПП). Тогда поможет такой трюк:

Если вставить в "При выгрузке" или в "После выгрузки" ПКО код:

УзелПараметра = СоздатьУзел("ЗначениеПараметра");
УстановитьАтрибут(УзелПараметра, "Имя", "СообщениеВсемуМиру");
ЗаписатьЭлемент(УзелПараметра, "Значение", "Здравствуй, Мир!");
ДобавитьПодчиненный(Приемник, УзелПараметра);

то в обработчике "После загрузки" этого ПКО параметр можно прочитать через соответствие "ПараметрыОбъекта":

НашПривет = ПараметрыОбъекта["СообщениеВсемуМиру"];

Здесь нужно прояснить несколько моментов, объясню на примере переноса плана счетов из 1С 77 в 1С 8.Х

Для ПКО "Хозрасчетный" для обработчика события "При выгрузке" напишем следующий код, где мы передадим характеристики передаваемого счета:

Код
Если Источник.Активный = 1 Тогда
   Вид = "Активный"
ИначеЕсли Источник.Активный = 2 Тогда
   Вид = "Пассивный"
Иначе
   Вид = "Активный/Пассивный"
КонецЕсли;

УзелПараметра = СоздатьУзел("ЗначениеПараметра");
УстановитьАтрибут(УзелПараметра, "Имя", "Вид");
УстановитьАтрибут(УзелПараметра, "Тип", "Строка");
ЗаписатьЭлемент(УзелПараметра, "Значение", Вид);
ДобавитьПодчиненный(Приемник, УзелПараметра);

УзелПараметра = СоздатьУзел("ЗначениеПараметра");
УстановитьАтрибут(УзелПараметра, "Имя", "Забалансовый");
УстановитьАтрибут(УзелПараметра, "Тип", "Число");
ЗаписатьЭлемент(УзелПараметра, "Значение", Источник.Забалансовый);
ДобавитьПодчиненный(Приемник, УзелПараметра);

УзелПараметра = СоздатьУзел("ЗначениеПараметра");
УстановитьАтрибут(УзелПараметра, "Имя", "Количественный");
УстановитьАтрибут(УзелПараметра, "Тип", "Число");
ЗаписатьЭлемент(УзелПараметра, "Значение", Источник.Количественный);
ДобавитьПодчиненный(Приемник, УзелПараметра);

УзелПараметра = СоздатьУзел("ЗначениеПараметра");
_УзелСсылки = ВыгрузитьПоПравилу(Источник.Родитель(),,,,"Хозрасчетный",,,,1);
УстановитьАтрибут(УзелПараметра, "Имя", "Родитель");
УстановитьАтрибут(УзелПараметра, "Тип", "ПланСчетовСсылка.Хозрасчетный");
ДобавитьПодчиненный(УзелПараметра, _УзелСсылки.cloneNode(1));
ДобавитьПодчиненный(Приемник, УзелПараметра);

Для к = 1 По 3 Цикл
   Если Источник.КоличествоСубконто() < к Тогда
      Прервать;
   Иначе
      УзелПараметра = СоздатьУзел("ЗначениеПараметра");
      _УзелСсылки = ВыгрузитьПоПравилу(Источник.ВидСубконто(к-1),,,,"ВидыСубконтоХозрасчетные",,,,1);
      УстановитьАтрибут(УзелПараметра, "Имя", "ВидСубконто"+Строка(к));
      УстановитьАтрибут(УзелПараметра, "Тип", "ПланВидовХарактеристикСсылка.ВидыСубконтоХозрасчетные");
      ДобавитьПодчиненный(УзелПараметра, _УзелСсылки.cloneNode(1));
      ДобавитьПодчиненный(Приемник, УзелПараметра);
      
      УзелПараметра = СоздатьУзел("ЗначениеПараметра");
      УстановитьАтрибут(УзелПараметра, "Имя", "Количественный"+Строка(к));
      УстановитьАтрибут(УзелПараметра, "Тип", "Число");
      ЗаписатьЭлемент(УзелПараметра, "Значение", Источник.Количественный);
      ДобавитьПодчиненный(Приемник, УзелПараметра);
      
      УзелПараметра = СоздатьУзел("ЗначениеПараметра");
      УстановитьАтрибут(УзелПараметра, "Имя", "ТолькоОбороты"+Строка(к));
      УстановитьАтрибут(УзелПараметра, "Тип", "Число");
      ЗаписатьЭлемент(УзелПараметра, "Значение", Источник.ТолькоОбороты(к-1));
      ДобавитьПодчиненный(Приемник, УзелПараметра);
   КонецЕсли;
КонецЦикла;


Во-первых, для чего тут
Код
УстановитьАтрибут(УзелПараметра, "Тип", "ПланСчетовСсылка.Хозрасчетный");

Это нужно для того, чтобы избежать ошибки при передаче пустой ссылки

Во-вторых, код
Код
_УзелСсылки = ВыгрузитьПоПравилу(Источник.Родитель(),,,,"Хозрасчетный",,,,1);

Обратите внимание, что я передаю лишний параметр в функции "ВыгрузитьПоПравилу", чуть позже я объясню зачем

В третьих, код
Код
ДобавитьПодчиненный(УзелПараметра, _УзелСсылки.cloneNode(1));

Здесь по сравнению с оригинальной статьей, я дописал "cloneNode(1)", иначе 1С 77 падала с ошибкой

Далее в том же ПКО в обработчике события "После выгрузки" напишем код
Код
Если НЕ Объект.Предопределенный И ПараметрыОбъекта<>Неопределено Тогда
   Объект.Родитель         = ПараметрыОбъекта.Получить("Родитель");
   Объект.Порядок         = Объект.ПолучитьПорядокКода();
   Объект.Количественный   = ПараметрыОбъекта.Получить("Количественный");
   Объект.Забалансовый      = ПараметрыОбъекта.Получить("Забалансовый");
   Вид                  = ПараметрыОбъекта.Получить("Вид");
   Если Вид = "Активный" Тогда
      Объект.Вид            = ВидСчета.Активный;
   ИначеЕсли Вид = "Пассивный" Тогда
      Объект.Вид            = ВидСчета.Пассивный;
   ИначеЕсли Вид = "Активный/Пассивный" Тогда
      Объект.Вид            = ВидСчета.АктивноПассивный;
   КонецЕсли;
   Если ПараметрыОбъекта["ВидСубконто1"] <> Неопределено Тогда
      Если Объект.ВидыСубконто.Количество() > 0 Тогда
         ВидСубконто = Объект.ВидыСубконто[0];
      Иначе
         ВидСубконто = Объект.ВидыСубконто.Вставить(0);
      КонецЕсли;
      ВидСубконто.ВидСубконто      = ПараметрыОбъекта["ВидСубконто1"];
      ВидСубконто.Количественный   = ПараметрыОбъекта["Количественный1"];
      ВидСубконто.ТолькоОбороты   = ПараметрыОбъекта["ТолькоОбороты1"];
   ИначеЕсли Объект.ВидыСубконто.Количество() > 0 Тогда
      Объект.ВидыСубконто.Удалить(0);
   КонецЕсли;
   Если ПараметрыОбъекта["ВидСубконто2"] <> Неопределено Тогда
      Если Объект.ВидыСубконто.Количество() > 1 Тогда
         ВидСубконто = Объект.ВидыСубконто[1];
      Иначе
         ВидСубконто = Объект.ВидыСубконто.Вставить(1);
      КонецЕсли;
      ВидСубконто.ВидСубконто      = ПараметрыОбъекта["ВидСубконто2"];
      ВидСубконто.Количественный   = ПараметрыОбъекта["Количественный2"];
      ВидСубконто.ТолькоОбороты   = ПараметрыОбъекта["ТолькоОбороты2"];
   ИначеЕсли Объект.ВидыСубконто.Количество() > 1 Тогда
      Объект.ВидыСубконто.Удалить(1);
   КонецЕсли;
   Если ПараметрыОбъекта["ВидСубконто3"] <> Неопределено Тогда
      Если Объект.ВидыСубконто.Количество() > 2 Тогда
         ВидСубконто = Объект.ВидыСубконто[2];
      Иначе
         ВидСубконто = Объект.ВидыСубконто.Вставить(2);
      КонецЕсли;
      ВидСубконто.ВидСубконто      = ПараметрыОбъекта["ВидСубконто3"];
      ВидСубконто.Количественный   = ПараметрыОбъекта["Количественный3"];
      ВидСубконто.ТолькоОбороты   = ПараметрыОбъекта["ТолькоОбороты3"];
   ИначеЕсли Объект.ВидыСубконто.Количество() > 2 Тогда
      Объект.ВидыСубконто.Удалить(2);
   КонецЕсли;
КонецЕсли;


Здесь я думаю все понятно, мы на основании переданных через параметры дополнительных характеристик счета создаем счет в базе Приемник.

Осталось только разобрать почему для функции "ВыгрузитьПоПравилу" я обозначил лишний параметр (см. выше)

Здесь в модуле обработки "V77Exp.ert" после того, как мы вставили код из файла "МодульВыгрузки.txt" мы произведем несколько изменений, а именно:

Во-первых, в самом начале переобъявим функцию "ВыгрузитьПоПравилу" следующим образом:
Код
Функция ВыгрузитьПоПравилу(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ИмяПКО = "", УзелСсылки = "", ТолькоПолучитьУзелСсылки = 0, НомерПКО = 0, ФлагПропустить = 0) Далее

Обратите внимание на лишний параметр "ФлагПропустить", вот его мы как раз и задействуем выше.

Во-вторых, найдем саму функцию "ВыгрузитьПоПравилу" и заменим заголовок на следующий:
Код
Функция ВыгрузитьПоПравилу(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ИмяПКО = "", УзелСсылки = "", ТолькоПолучитьУзелСсылки = 0, 
   НомерПКО = 0, ФлагПропустить = 0)

Здесь все логично и понятно

И последнее, найдем в функции "ВыгрузитьПоПравилу" код, который обрабатывает обработчик события "При выгрузке", ведь именно в ней мы прописали нестандартный код для передачи параметров. Если мы оставим этот код по умолчанию, то 1С 77 будет вываливаться с ошибкой, поэтому, используя параметры "ФлагПропустить", мы обойдем этот код, вот так:
Код
Если (ПолучитьРеквизитПКО(НомерПКО, "ПриВыгрузке") = 1) И (ФлагПропустить = 0) Тогда

Таким образом, мы передали дополнительные характеристики счета из 1С 77 в 1С 8.Х
Спасибо и удачи всем!
DevИспользуете ли вы механизм Системы Взаимодействия?#227 19.07.18 9:22
(223)
Цитата
Бред, приведите пример такого супер-пупер нужного функционала, который проблематично реализовать на обычных формах и который уже есть и без которого бизнес в гору никак не пойдет?
Коллега полностью поддерживаю - нет такого нужного функционала на УФ, которое нельзя сделать на обычных формах.
Предыдущий автор - классический менеджер. Помните в американских фильмах есть персонажи - страховой агент - цель которого втюхать очередному дурачку "кучу супер-пупер функционала" за бешенные деньги? Он оттуда
DevИспользуете ли вы механизм Системы Взаимодействия?#226 19.07.18 9:15
(222)
Цитата
Как я люблю такие речи :)
А мы как любим :)
А если по серьезному:
1. Я за движение вперед, но не в ущерб функционалу. До сих пор есть множество клиентов, которые работают на 1С 77 и вполне довольны. Как правило это мелкие или чуть средние фирмы. Нет такого функционала (не учитываем "свистульки","рюшки" и прочее) в 1С 8.3, которое не возможно было реализовать в 1С 77. А кто скажет, что нельзя, невозможно - это значит познания в области программирования "ограничены", т.е., классический 1С-ник, который окромя, того, чему его научили в так называемых "курсах программирования по 1С 8" и методичкам от фирмы 1С - БОЛЬШЕ ничего не умеет.
2. По поводу
Цитата
Проблема всех этих клиентов в том, что когда бизнес идет вгору - софт становится уязвимым местом, и клиент теряет конкурентное приимущество. От кучи функционала клиент отказывается, так как это дорого сделать на обычных формах и т.д.
Лучше меньше да лучше - есть такая старая народная мудрость. "Куча функционала" больше смахивает на "кучу понтов". Нормальный хозяйственник 7 раз подумает, прежде чем, переходить на что-то новое (это касается не только софта от 1С). Открою для автора большой секрет, многие десктопы до сих пор эксплуатируют Windows XP.
3. По поводу
Цитата
Попробоуйте в обыных формах применить расширения, например, я далеко уже не хочу.
Попробуйте сделать группировку в списке документов, или скрыть вывести доп реквизиты?
А зачем в мелких конторах, у которых либо самописннные, либо сильно доработанные - РАСШИРЕНИЯ? Там давно уже положили на поддержку. Дешевле заплатить прогеру, чем абон плату фирме-поставщику. А че группировка документов - такая критическая необходимость? Скрыть, вывести доп. реквизиты на 1С 77 - раз плюнуть...

В целом и в общем - я за движуху...но это не означает БРОСАЙТЕ ВСЕ и СРОЧНО переходите на 1С 8.3 или на 1С 8.4 - ТОЛЬКО ПОТОМУ ЧТО ПОЯВИЛАСЬ новая кнопка или новое финтифлюшку - я ПРОТИВ!
DevМинимализмы 3#32 13.04.18 9:19
(28)

ОШИБОЧКА У меня :) я неправильно выполнял тесты. Сейчас вижу, что был неправ!

ВЫ правы коллега, я перепроверил еще раз - метод Автора быстрее.

В споре рождается истина - рад был поспорить с вами.

Единственно, все еще пока сомневаюсь - это расход ОЗУ.

Со всем уважением!
DevМинимализмы 3#31 13.04.18 8:56
(28)
Опять же по поводу как формируется ТЗ. ТЗ можно формировать по разному, но вот удалить строки, как автор утверждает - быстрее всего ТАК!

Ремарка к "Это шутка! Не смешно"

Я тз к удалению подаю через запрос.

Цитата
69. Быстрое удаление строк в таблице значений
Удаление строк в таблице значений

Быстрее всего удаляются строки путем копирования оставшихся строк по условию, обратному к условию удаления:

РабочаяТаблица = РабочаяТаблица.Скопировать(Новый Структура("КУдалению", Ложь))
DevМинимализмы 3#30 13.04.18 8:51
(28)
Цитата
ТекущаяУниверсальнаяДатаВМиллисекундах

я тестирую на 1С 8.1 и смотрю через замер производительности
DevМинимализмы 3#29 13.04.18 8:45
(28)
Нет не шутка

Вариант 1 - ваше тз на вход через запрос

Код
Процедура СформироватьРабочуюТаблицу()
   //тз = Новый ТаблицаЗначений;
   //тз.Колонки.Добавить("Номер", Новый ОписаниеТипов("Число"));
   //тз.Колонки.Добавить("КУдалению",Новый ОписаниеТипов("Булево"));
   //Для к=1 По 300000 Цикл
   //   СтрТЗ = тз.Добавить();
   //   СтрТЗ.Номер = к;
   //   СтрТЗ.КУдалению = к%2 = 0;
   //КонецЦикла;
   //
   //Запрос = Новый Запрос;
   //Запрос.УстановитьПараметр("ВнешнийИсточник", тз);
   //Запрос.Текст = 
   //"ВЫБРАТЬ
   //|   ВН.Номер КАК Номер,
   //|   ВН.КУдалению КАК КУдалению
   //|ПОМЕСТИТЬ втВрем
   //|ИЗ
   //|   &ВнешнийИсточник КАК ВН
   //|;
   //|
   //|////////////////////////////////////////////////////////////////////////////////
   //|ВЫБРАТЬ
   //|   втВрем.Номер,
   //|   втВрем.КУдалению
   //|ИЗ
   //|   втВрем КАК втВрем";
   //РабочаяТаблица = Запрос.Выполнить().Выгрузить();
      
   РабочаяТаблица.Индексы.Добавить("КУдалению");
   Сообщить(РабочаяТаблица.Количество());
КонецПроцедуры

Процедура Кнопка1Нажатие(Элемент)
   СформироватьРабочуюТаблицу();
   найдСтр = РабочаяТаблица.НайтиСтроки(Новый Структура("КУдалению",Истина));
   Для к = 0 По найдСтр.ВГраница() Цикл
      РабочаяТаблица.Удалить(найдСтр[к]);
   КонецЦикла;
   Сообщить(РабочаяТаблица.Количество());
КонецПроцедуры

Процедура Кнопка2Нажатие(Элемент)
   СформироватьРабочуюТаблицу();
   РабочаяТаблица = РабочаяТаблица.Скопировать(Новый Структура("КУдалению",Истина));
   Сообщить(РабочаяТаблица.Количество());
КонецПроцедуры


Результаты в ВАШУ пользу

вариант 2 - скажем так вот выглядит

Код
Процедура СформироватьРабочуюТаблицу()
   Запрос = Новый Запрос;
   Запрос.Текст = 
   "ВЫБРАТЬ
   |   ПриходТовары.Ссылка,
   |   ПриходТовары.НомерСтроки,
   |   ПриходТовары.Номенклатура,
   |   ПриходТовары.Склад,
   |   ПриходТовары.Контрагент,
   |   ПриходТовары.ДоговорКонтрагента,
   |   ПриходТовары.Партия,
   |   ПриходТовары.Количество,
   |   ПриходТовары.ЦенаПоставки,
   |   ПриходТовары.Сумма,
   |   ПриходТовары.НаценкаОпт,
   |   ПриходТовары.НаценкаРозн,
   |   ПриходТовары.КодКБ,
   |   ЛОЖЬ КАК КУдалению
   |ИЗ
   |   Документ.Приход.Товары КАК ПриходТовары
   |ГДЕ
   |   ПриходТовары.Ссылка.Дата МЕЖДУ &Дата1 И &Дата2";
   Запрос.УстановитьПараметр("Дата1", НачалоГода(ТекущаяДата()));
   Запрос.УстановитьПараметр("Дата2", ТекущаяДата());
   
   РабочаяТаблица = Запрос.Выполнить().Выгрузить();
   
   Счетчик = 1;
   Для каждого ТС из РабочаяТаблица Цикл
      Если Счетчик = 1 Тогда
         ТС.КУдалению = Истина;
         Счетчик = 0;
      Иначе
         Счетчик = 1;
      КонецЕсли;
   КонецЦикла;
   
   РабочаяТаблица.Индексы.Добавить("КУдалению");
   Сообщить(РабочаяТаблица.Количество());
КонецПроцедуры

Процедура Кнопка1Нажатие(Элемент)
   СформироватьРабочуюТаблицу();
   найдСтр = РабочаяТаблица.НайтиСтроки(Новый Структура("КУдалению",Истина));
   Для к = 0 По найдСтр.ВГраница() Цикл
      РабочаяТаблица.Удалить(найдСтр[к]);
   КонецЦикла;
   Сообщить(РабочаяТаблица.Количество());
КонецПроцедуры

Процедура Кнопка2Нажатие(Элемент)
   СформироватьРабочуюТаблицу();
   РабочаяТаблица = РабочаяТаблица.Скопировать(Новый Структура("КУдалению",Истина));
   Сообщить(РабочаяТаблица.Количество());
КонецПроцедуры


результаты в МОЮ пользу
DevМинимализмы 3#27 13.04.18 8:10
(26)
Ну что же, теперь понятно, почему у вас отличные результаты чем у меня
вот как выглядит мой тест

Код
Процедура СформироватьРабочуюТаблицу()
   Запрос = Новый Запрос;
   Запрос.Текст = 
   "ВЫБРАТЬ *, ЛОЖЬ КАК КУдалению........";

   РабочаяТаблица = Запрос.Выполнить().Выгрузить();
   
   Счетчик = 1;
   Для каждого ТС из РабочаяТаблица Цикл
      Если Счетчик = 1 Тогда
         ТС.КУдалению = Истина;
         Счетчик = 0;
      Иначе
         Счетчик = 1;
      КонецЕсли;
   КонецЦикла;

   РабочаяТаблица.Индексы.Добавить("КУдалению");
   Сообщить(РабочаяТаблица.Количество());
КонецПроцедуры

Процедура Кнопка1Нажатие(Элемент)
   СформироватьРабочуюТаблицу();
   найдСтр = РабочаяТаблица.НайтиСтроки(Новый Структура("КУдалению",Истина));
   Для к = 0 По найдСтр.ВГраница() Цикл
      РабочаяТаблица.Удалить(найдСтр[к]);
   КонецЦикла;
   Сообщить(РабочаяТаблица.Количество());
КонецПроцедуры

Процедура Кнопка2Нажатие(Элемент)
   СформироватьРабочуюТаблицу();
   РабочаяТаблица = РабочаяТаблица.Скопировать(Новый Структура("КУдалению",Истина));
   Сообщить(РабочаяТаблица.Количество());
КонецПроцедуры


я подаю на вход ТЗ из запроса, вы - нет....поэтому результаты тестов у нас разные

Так что и я прав и вы правы.....
DevМинимализмы 3#25 12.04.18 10:04
(23)
Порадовало :) автор пишет, что:

Цитата
Быстрее всего удаляются строки путем копирования оставшихся строк по условию, обратному к условию удаления

которое оказывается на самом деле - это:
Цитата

Быстрее всего удаляются строки путем копирования оставшихся строк по условию, обратному к условию удаления". При достаточно большой ТЗ, когда индексация начинает оказывать положительный результат, с индексацией нужной колонки

Ну и конечно напоследок

Но последнее предложение должно пониматься нормальным разработчиком по-умолчанию

Я бы дописал

Нормальные разработчики
- это разработчики, у которых есть телепатическая супер сила. Это шутка :)! Да, я прочитал ссылку выше к задаче 69. И все равно считаю, что удалить моим способ быстрее и самое главнее надежнее. Представьте у вас в ТЗ ярды строк, способ предложенный автором на короткое время создаст 2 копии ТЗ с 2-кратным потреблением ОЗУ (на 1-ю и 2-ю ТЗ), потом конечно 1-я удалится. Но что если у вас ОЗУ на 2 ТЗ не хватит? Получите банально "Недостаточно памяти".

Со всем уважением!