Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
22 ноя 2024, 20:59

Присвоение записи в справочнике Родителя (БУ4,5 (77,484))

Автор Sashenka, 25 мар 2010, 08:56

0 Пользователей и 1 гость просматривают эту тему.

Sashenka

Доброго времени суток, помогите пожалуйста разобрать...
Есть задача сделать в справочнике разноску, т.е. на верхнем уровне есть записи, которые туда добавляются из выгрузки ЗП, нужно разнести их по группам. В общем я все почти написал, но у меня проблемам в присвоении записи родителя. Вот мой код.


Перем темп; 
Перем темп2;
Перем ДСписания;
Перем ФлагД;
Перем КодГ;   
Перем СпЭл;

//*******************************************

Процедура Сформировать()

Спр = СоздатьОбъект("Справочник.РасходыБудущихПериодов");   
СпзЗ = СоздатьОбъект("СписокЗначений");
СпзГ = СоздатьОбъект("СписокЗначений");

//-- подготовка списков для обработки не разнесенных записей

Спр.ВыбратьЭлементы();
Пока (Спр.ПолучитьЭлемент() > 0) цикл
    Если Спр.Уровень() = 1 Тогда
темп = Спр.Наименование;
Если (Найти(ВРег(темп),ВРег("оплата труда")) > 0) Тогда
  Если Спр.ЭтоГруппа() <> 1 Тогда
СпзЗ.ДобавитьЗначение(Спр.Код,Спр.Код);
  КонецЕсли;
КонецЕсли;
Если (Найти(ВРег(темп),ВРег("Расходы по з/п")) > 0) Тогда
Если Спр.ЭтоГруппа()=1 Тогда
СпзГ.ДобавитьЗначение(Спр.Код,Спр.Код);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
   
//-- обработка справочника


Если СпзЗ.РазмерСписка() > 0 Тогда
 
//-------- обработка списка
Для А = 1 по СпзЗ.РазмерСписка() Цикл
темп="";
СпзЗ.ПолучитьЗначение(А,темп);
Спр.НайтиПоКоду(темп);
Если Спр.Выбран() > 0 Тогда 
Если Спр.Уровень() = 1 Тогда
ДСписания= ДатаГод(Спр.ДатаОкончанияСписания); //-- получение даты обработки

Для Б = 1 по СпзГ.РазмерСписка() Цикл //-- обработка групп 
темп2="";
СпзГ.ПолучитьЗначение(Б,темп2);
Спр.НайтиПоКоду(темп2);
ФлагД = 0;
Если Спр.Выбран() > 0 Тогда
Если Спр.Уровень() = 1 Тогда
  Если (Найти(ВРег(Спр.Наименование),ВРег(ДСписания)) > 0) Тогда
  Если Спр.ЭтоГруппа() = 1 Тогда
ФлагД = 1;
КодГ = темп2;                 
КонецЕсли;
  КонецЕсли;
КонецЕсли;
КонецЕсли;

Если ФлагД = 1 Тогда //-- если группа найдена тогда переносим значение

  Спр.НайтиПоКоду(темп);
                          СпЭл = Спр.ТекущийЭлемент();
  //Сообщить(Спр.Наименование);
  Спр.НайтиПоКоду(КодГ);
  //Сообщить(Спр.Наименование);
  СпЭл.Родитель = Спр.ТекущийЭлемент();
  СпЭл.Записать();


Иначе // --- если группа не найдена созадем ее и переносим значение

       //     Если Б = СпзГ.РазмерСписка() Тогда
// Спр.НоваяГруппа();
// Спр.Наименование = "Расходы по з/п "+ДСписания+" год";
// Спр.Записать();
// Спр.НайтиПоНаименованию("Расходы по з/п "+ДСписания+" год");                                                           
// СпзГ.ДобавитьЗначение(Спр.Код,Спр.Код);
// КодГ = Спр.Код;
// Спр.НайтиПоКоду(темп);
// СпЭл = Спр;
// Спр.НайтиПоКоду(КодГ);
// СпЭл.Родитель = Спр.ТекущийЭлемент();
//   СпЭл.Записать();                 
//   КонецЕсли;



КонецЕсли;

КонецЦикла;
                         
КонецЕсли;
КонецЕсли;


КонецЦикла;

     Предупреждение("Разноска данных завершена!",60);
Форма.Закрыть();
Иначе
Предупреждение("Сведения в справочнике в разноске не нуждаются!",60);
КонецЕсли;
КонецПроцедуры



В общем если пишут так

  Спр.НайтиПоКоду(темп);
                          СпЭл = Спр.ТекущийЭлемент();
  //Сообщить(Спр.Наименование);
  Спр.НайтиПоКоду(КодГ);
  //Сообщить(Спр.Наименование);
  СпЭл.Родитель = Спр.ТекущийЭлемент();
  СпЭл.Записать();


У меня выходит ошибка
Цитировать
СпЭл.Родитель = Спр.ТекущийЭлемент();
{Отчет.РазноскаПоОплатеТруда.Форма.Модуль(72): Объект не может быть перепозиционирован!}

А вот если я пишу так
  Спр.НайтиПоКоду(темп);
                          СпЭл = Спр;
  //Сообщить(Спр.Наименование);
  Спр.НайтиПоКоду(КодГ);
  //Сообщить(Спр.Наименование);
  СпЭл.Родитель = Спр.ТекущийЭлемент();
  СпЭл.Записать();

У меня 1С уходит в никуда.. т.е. начинает работать и виснет... сказать по правде.. я особо трейсом не гонял ее, но если правильно понял зависает на
Если (Найти(ВРег(Спр.Наименование),ВРег(ДСписания)) > 0) Тогда
А это уже не очень логично... но при снятии 1С с процессов соответственно ломается после индексации справочник.. в общем глюк в базе получается..

Хотел бы спросить, как правильно назначить записи родителя???

Sashenka

Да забыл сказать... прежде чем 1С зависнуть.. одну запись она обрабатывает.. т.е. вроде (судя по трассировки) записать() один раз работает.

Tatitutu

СпЭл.ИспользоватьРодителя(Спр.ТекущийЭлемент());
И еще желательно сделать проверку
Если  Спр.НайтиПоКоду(КодГ)=1 Тогда
//мы нашли родителя
   СпЭл.ИспользоватьРодителя(Спр.ТекущийЭлемент());
Иначе
//нет такого элемента
....//Ваши действия
КонецЕсли;

*  MAGAZKA - лучшая программа для розничного магазина (с) *

Sashenka

Спасибо за ответ.
Но есть нюанс..
Если я использую как Вы сказали


Если ФлагД = 1 Тогда //-- если группа найдена тогда переносим значение
  Спр.НайтиПоКоду(темп);
                          СпЭл = Спр.ТекущийЭлемент();
  Если Спр.НайтиПоКоду(КодГ)=1 Тогда
  СпЭл.ИспользоватьРодителя(Спр.ТекущийЭлемент());    
            Спр.Записать();
  КонецЕсли;


Ничего не происходит... при открытии самого справочника 1С бухгалтерии люди как были не в группе на верхнем уровне так и остались.
Если делать так

Если ФлагД = 1 Тогда //-- если группа найдена тогда переносим значение
  Спр.НайтиПоКоду(темп);
                          СпЭл = Спр.ТекущийЭлемент();
  Если Спр.НайтиПоКоду(КодГ)=1 Тогда
  СпЭл.ИспользоватьРодителя(Спр.ТекущийЭлемент());    
            СпЭл.Записать();
  КонецЕсли;


А именно
СпЭл.Записать();
То будет ошибка
ЦитироватьНе выбран элемент!
При трассеровке на первом шаге есть значение СпЭл, и после поиска по коду КодГ, значение Спр.ТекущийЭлемент() тоже есть... :dfbsdfbsdf:

Tatitutu

Давайте пошагово разберем , что Вы тут написали
А что должно произойти , если Вы нечего и не делаете

Если ФлагД = 1 Тогда //-- если группа найдена тогда переносим зн

Спр.НайтиПоКоду(темп); //ищем что что по коду    НайтиПоКоду(<Код>,<ФлагПоиска>) про флагПоиска Вы забываете
//будем считать что нашли

СпЭл = Спр.ТекущийЭлемент();
//теперь СпЭл - это ссылка на тот элемент
Если Спр.НайтиПоКоду(КодГ)=1 Тогда
//нашли
СпЭл.ИспользоватьРодителя(Спр.ТекущийЭлемент());
//так не пойдет это для выборки нужно
Спр.Записать();  
//можно не записывать Вы ничего и не меняли

КонецЕсли;


я наверное немного не правильно Вас понял
в Вашем коде нужно внести поправку:


Спр.НайтиПоКоду(темп);
СпЭл = Спр.ТекущийЭлемент;             //нашли элемент , запомнили
//Сообщить(Спр.Наименование);
Спр.НайтиПоКоду(КодГ);                    //нашли родителя запомнили
//Сообщить(Спр.Наименование);
СпЭл.Родитель = Спр.ТекущийЭлемент(); //присвоили - перенесли в другую группу
Спр.Записать(); //а не СпЭл.Записать()

*  MAGAZKA - лучшая программа для розничного магазина (с) *

Sashenka

Мне необходимо в справочнике перенсти запись находящуюся на 1 уровне в нужную мне группу.
т.е.
спр
---
увк (групп)
век(групп)
запись1
запись2

Мне надо запись1 занести в увк

чтоб было
спр
---
увк(групп)
век(групп)
запись2

а при раскрытии увк было
увк(групп)
---
запись 1

Я сделал так как было раньше с учетом своей невнимательности


Спр.НайтиПоКоду(темп);
СпЭл = Спр;
Спр.НайтиПоКоду(КодГ);
СпЭл.Родитель = Спр.ТекущийЭлемент();
Спр.Записать();


запустил.. и сейчас у меня 1С уже минуты 3 висит с надписью выполняется обработка...

Если я сделаю как вы написали


Спр.НайтиПоКоду(темп);
СпЭл = Спр.ТекущийЭлемент;
Спр.НайтиПоКоду(КодГ);
СпЭл.Родитель = Спр.ТекущийЭлемент();
Спр.Записать();


У меня будет ошибка "Поле агрегатного типа не обноружено (текущийЭлемент)"

Если я сделаю

Спр.НайтиПоКоду(темп);
СпЭл = Спр.ТекущийЭлемент();
Спр.НайтиПоКоду(КодГ);
СпЭл.Родитель = Спр.ТекущийЭлемент();
Спр.Записать();


У меня будет ошибка "Объект не может быть перепозиционирован!"

Sashenka

Я сделал
написал так

Спр.НайтиПоКоду(темп);
Спр1 = СоздатьОбъект("Справочник.РасходыБудущихПериодов");
Спр1.НайтиПоКоду(КодГ);
Спр.Родитель = Спр1.ТекущийЭлемент();
Спр.Записать();


А вообще конечно странно... почему он через переменную не захотел идти...  <_<
Уважаемый Tatitutu, спасибо за помощь

Tatitutu

так правильно. Вы делаете наоборот.
Сначала найдите РОДИТЕЛЯ (а не элемент)
потом найдите элемент и присвойте ему родителя.
Запишите. Все

было
Спр.НайтиПоКоду(темп);
СпЭл = Спр.ТекущийЭлемент();
Спр.НайтиПоКоду(КодГ);
СпЭл.Родитель = Спр.ТекущийЭлемент();
Спр.Записать();


правильно
Спр.НайтиПоКоду(КодГ);
СпРод = Спр.ТекущийЭлемент(); //это нашли группу куда перенести
Спр.НайтиПоКоду(темп); //нашли элемент который нужно перенести
Спр.Родитель = СпРод; //поменяли родителя
Спр.Записать(); //и записали

*  MAGAZKA - лучшая программа для розничного магазина (с) *

Sashenka

Цитата: Tatitutu от 25 мар 2010, 10:38
так правильно. Вы делаете наоборот.
Сначала найдите РОДИТЕЛЯ (а не элемент)
потом найдите элемент и присвойте ему родителя.
Запишите. Все

было
Спр.НайтиПоКоду(темп);
СпЭл = Спр.ТекущийЭлемент();
Спр.НайтиПоКоду(КодГ);
СпЭл.Родитель = Спр.ТекущийЭлемент();
Спр.Записать();


правильно
Спр.НайтиПоКоду(КодГ);
СпРод = Спр.ТекущийЭлемент(); //это нашли группу куда перенести
Спр.НайтиПоКоду(темп); //нашли элемент который нужно перенести
Спр.Родитель = СпРод; //поменяли родителя
Спр.Записать(); //и записали


А в чем различие? о.О
сказать по правде я не особо понял...
Если я результат сохраняю в переменную.
Т.е. делаю выборку из базы.. сохраняю результат в переменную.. делаю другую выборку из базы и определенному реквизиту даю данные из переменной...
Сказать по правде разницы не понял..  :dfbbdrfb:

Tatitutu

Я сделал так как было раньше с учетом своей невнимательности

Код:

Спр.НайтиПоКоду(темп);
СпЭл = Спр;                                              //спр - это ссылка на весь справочник, а не на элемент
Спр.НайтиПоКоду(КодГ);
СпЭл.Родитель = Спр.ТекущийЭлемент();
Спр.Записать();


запустил.. и сейчас у меня 1С уже минуты 3 висит с надписью выполняется обработка...

Если я сделаю как вы написали

Код:

Спр.НайтиПоКоду(темп);
СпЭл = Спр.ТекущийЭлемент;                            //ошибка к коде нужно Спр.ТекущийЭлемент();
Спр.НайтиПоКоду(КодГ);
СпЭл.Родитель = Спр.ТекущийЭлемент();
Спр.Записать();


У меня будет ошибка "Поле агрегатного типа не обноружено (текущийЭлемент)"

Если я сделаю
Код:

Спр.НайтиПоКоду(темп);
СпЭл = Спр.ТекущийЭлемент();                                          //это ТЕКУЩИЙ ЭЛЕМЕНТ
Спр.НайтиПоКоду(КодГ);                                                    //здесь он меняется
СпЭл.Родитель = Спр.ТекущийЭлемент();                         
//вот здесь НЕ ПРИСВАИВАТЕТСЯ, потому что нужно объект найти (спозиционировать) а потом присвовоить значение
// я поэтому и написал , нужно Найти ссылку на РОДИТЕЛЯ (запомнить) а потом находить элементы , присваивать родителя и записывать изменения
Спр.Записать();


У меня будет ошибка "Объект не может быть перепозиционирован!"

*  MAGAZKA - лучшая программа для розничного магазина (с) *

Теги:

Похожие темы (5)

Рейтинг@Mail.ru

Поиск