Имя: Пароль:
1C
1C 7.7
v7: Ошибка: Неверный тип справочника!
,
0 MathaiShung
 
22.03.16
19:39
Процедура МодификацияСправочника()
    Спр=СоздатьОбъект("Справочник.Номенклатура");
    Спр.ВыбратьЭлементы();
    ТЗ.ВыбратьСтроки();
    НомСтр=0;
    Пока ТЗ.ПолучитьСтроку()=1 Цикл
        НомСтр=НомСтр+1;
        Подчинение=ТЗ.ПолучитьЗначение(НомСтр,1);
        Код=ТЗ.ПолучитьЗначение(НомСтр,2);
        Наименование=ТЗ.ПолучитьЗначение(НомСтр,3);
        Если Спр.НайтиПоКоду(Код,0)=0 Тогда
            Если Спр.НайтиПоКоду(Подчинение,0)=1 Тогда
                Родитель=Спр;
            КонецЕсли;
            Гр=СоздатьОбъект("Справочник.Номенклатура");
            Гр.НоваяГруппа();
            Гр.УстановитьАтрибут("Код",Код);
            Гр.УстановитьАтрибут("Наименование",Наименование);
            Гр.УстановитьАтрибут("Родитель",Родитель);
            Гр.Записать();    
        Иначе
            Спр.УстановитьАтрибут("Наименование",Наименование);
            Спр.УстановитьАтрибут("Родитель",Родитель);
            Спр.Записать();
            Если Спр.НайтиПоКоду(Подчинение,0)=1 Тогда
                Родитель=Спр.ТекущийЭлемент();
            КонецЕсли;
        КонецЕсли
    КонецЦикла;
КонецПроцедуры

На этапе Спр.УстановитьАтрибут("Родитель",Родитель) возникает эта ошибка, хотя несколькими строками ранее, когда устанавливал Родителя создаваемой группе никакой ошибки не выдавалось - всё установилось нормально.
1 hhhh
 
22.03.16
19:47
потому что не определен вообще этот Родитель.

      Иначе
            Спр.УстановитьАтрибут("Наименование",Наименование);
            Спр.УстановитьАтрибут("Родитель",Родитель);


где определяешь? В каком месте?
2 MathaiShung
 
22.03.16
19:55
(1) Я специально перед определением устанавливаю, потому что если после поставить - тогда Спр начинает выдавать только Родителя вместо всех элементов. Проверил - поставил Сообщить(Родитель) перед его определением - выдаёт всё верно.
3 ДенисЧ
 
22.03.16
19:59
Попробуй .ТекущийЭлемент()...
4 MathaiShung
 
22.03.16
20:12
(3) Пробовал - тогда если Родителя получать перед определением - выдаются все элементы, если после - нормально, только родитель, но тогда я не смогу обратиться к элементу чтобы его атрибут установить, т.к. Спр после определения Родителя возвращает тоже Родителя вместо элемента.
5 Chameleon1980
 
22.03.16
20:19
а тут зачем

        Подчинение=ТЗ.ПолучитьЗначение(НомСтр,1);
        Код=ТЗ.ПолучитьЗначение(НомСтр,2);
        Наименование=ТЗ.ПолучитьЗначение(НомСтр,3);


мы и так по тз бежим

        Подчинение=ТЗ.Подчинение;
        Код=ТЗ.Код;
        Наименование=ТЗ.Наименование;

или конкретно по номеру колонки нужно?
6 MathaiShung
 
22.03.16
20:24
(5) Я в ТЗ идентификаторов не устанавливал - она у меня выгружается из ecxel, так что по номеру обращаюсь
7 MathaiShung
 
22.03.16
21:31
Проблему с обращением к элементу решил с помощью ещё одного позиционирования. Теперь и Родитель устанавливается после его определения, и ТекущийЭлемент убрал, но ошибка осталась!
Пока ТЗ.ПолучитьСтроку()=1 Цикл
        НомСтр=НомСтр+1;
        Подчинение=ТЗ.ПолучитьЗначение(НомСтр,1);
        Код=ТЗ.ПолучитьЗначение(НомСтр,2);
        Наименование=ТЗ.ПолучитьЗначение(НомСтр,3);
        Если Спр.НайтиПоКоду(Код,0)=0 Тогда
            Если Спр.НайтиПоКоду(Подчинение,0)=1 Тогда
                Родитель=Спр;
            КонецЕсли;
            Гр=СоздатьОбъект("Справочник.Номенклатура");
            Гр.НоваяГруппа();
            Гр.УстановитьАтрибут("Код",Код);
            Гр.УстановитьАтрибут("Наименование",Наименование);
            Гр.УстановитьАтрибут("Родитель",Родитель);
            Гр.Записать();    
        Иначе
            //Спр.УстановитьАтрибут("Наименование",Наименование);
            //Спр.Записать();
            Если Спр.НайтиПоКоду(Подчинение,0)=1 Тогда
                Родитель=Спр;
            КонецЕсли;
            Тов=СоздатьОбъект("Справочник.Номенклатура");
            Если Тов.НайтиПоКоду(Код,0)=1 Тогда
                Товар=Тов;
            КонецЕсли;
            Товар.УстановитьАтрибут("Родитель",Родитель);
            Товар.Записать();
        КонецЕсли
    КонецЦикла;

По-прежнему - Неверный тип справочника! Причём для новых групп установить Родителя аналогичным образом удалось без всяких ошибок. Кто-нибудь знает почему так происходит и как с этим бороться?
8 Scandsv
 
22.03.16
21:38
Зачем .УстановитьАтрибут()????
Тут просто

спр.Родитель = Родитель;
спр.Записать();

и все....
9 MathaiShung
 
22.03.16
21:39
(8) Так тоже делал - результат не меняется: Неверный тип справочника!
10 Злопчинский
 
22.03.16
21:43
Пристально не смотрел
Но мне кардинально не нравится
Что внутри условия если родитель присваивается но только пр выполнении условия а ниже по тексту кода используется родитель - какое значение если условие не сработало?

И писать правильно
Родитель = спр.текущийэлемент();
11 MathaiShung
 
22.03.16
21:49
(10) У меня с ТекущимЭлементом и было изначально (0), это уже тут насоветовали - поменял.
Если условие не сработает, значит нечего менять - по задумке должны переименовываться и переструктурироваться элементы справочника, коды которых соответствуют кодам из ТЗ.
12 Злопчинский
 
22.03.16
21:50
Пока ...... Цикл
    Родитель = ПолучитьПустоеЗначение("Справочник.Номенклатура");
    Далее по тексту


Сделать для начала
13 Злопчинский
 
22.03.16
21:51
(11)  не путай бодий дар и палец как говорится
У тебя родитель для текущей строки тз определяется каждый раз или может оставаться от предыдущей строки тз
?
14 Scandsv
 
22.03.16
21:53
(9) а родитель - точно папка????
А то может ты элемент справочника в родители суешь?
а туда только группу можно лепить
15 Злопчинский
 
22.03.16
21:53
Для начала сделай (12)
И сюда доклад
16 Злопчинский
 
22.03.16
21:53
(14)  угу, запросто
Проверки то нет что жто группа
17 MathaiShung
 
22.03.16
21:54
(13) Каждый раз определяется по коду из столбца Подчинение
18 MathaiShung
 
22.03.16
21:56
(14) Точно, это в ТЗ уже чётко установлено
19 Злопчинский
 
22.03.16
21:56
(17)  тогда твой код однозначно кривой по логике построения
20 Злопчинский
 
22.03.16
21:59
Если у тебя ВСЕГДА условие =1


            Если Спр.НайтиПоКоду(Подчинение,0)=1 Тогда
                Родитель=Спр;


ТО ЗАЧЕМ ПРОВЕРЯТЬ ЭТО УСЛОВИЕ?
Если не всегда условие=1 - то где ветка иначе?
21 Scandsv
 
22.03.16
22:00
(18) Все, что точно определено должно быть 100% проверено.
Перед тем как установить родителем - проверку делай на то, что элемент который будет родителем группа.
22 Злопчинский
 
22.03.16
22:00
Если нет ветки Иначе
То внизу используемая переменная родитель - какое значение ДОЛЖНА ИМЕТЬ?
23 Scandsv
 
22.03.16
22:01
И если не группа пусть тебе сообщение выдаст - все увидишь. 99.99% что лепишь родителем элемент справочника. Чупа чупс ставлю.
24 Garykom
 
гуру
22.03.16
22:02
Никому не кажется этот код немного странным?


Если Спр.НайтиПоКоду(Код,0)=0 Тогда
            Если Спр.НайтиПоКоду(Подчинение,0)=1 Тогда
                Родитель=Спр;
            КонецЕсли;
25 Злопчинский
 
22.03.16
22:02
(23)  присоединяюсь к рекомендации
26 MathaiShung
 
22.03.16
22:02
(20) Да, условие будет всегда 1. Я таким образом позиционируюсь на нужном элементе и получаю Родителя. Или можно ещё как-то?
27 Злопчинский
 
22.03.16
22:04
Если условие ВСЕГДА =1
То нахрена это проверять?

И почему ты уверен что всегда?
28 MathaiShung
 
22.03.16
22:05
(24) И что здесь странного? Сначала проверяется код элемента, потом код Родителя этого элемента.
29 Злопчинский
 
22.03.16
22:05
(24)  да хз
30 Злопчинский
 
22.03.16
22:06
(28)  херню городите
В части "этого элемента"
31 Scandsv
 
22.03.16
22:07
(26) ты ищешь в справочнике элемент по коду.
допустим ты его нашел. ТЫ уверен, что нашел группу? когда она была создана. Может элемент с этим кодом и не группа вовсе. Ты это не проверяешь..

а ведь кто не дает добавить

Если Родител.ЭтоГруппа() Тогда
         спр.родитель = родитель;
         спр.Записать();
Иначе
         Сообщить(Родитель.Код+"Нифига не группа");
КонецЕсли;

Вот три секунды а сколько пользы
32 Злопчинский
 
22.03.16
22:07
Логика какаято типа
Если не нашли элемент по коду
То ищем группу по коду группы
33 Scandsv
 
22.03.16
22:09
(24) не странно
34 Garykom
 
гуру
22.03.16
22:09
35 Scandsv
 
22.03.16
22:09
Коряво, но не странно
36 Scandsv
 
22.03.16
22:11
Он предполагает, что в ТЗ в одной колонке коды элементов, а в другой коды их родителей
37 MathaiShung
 
22.03.16
22:11
(27) Я же говорю, это не ради проверки, а для получения значения Родителя. А нет, не всегда - если группа первого уровня, кода в колонке Подчинение не будет, этот момент пропустил.
38 Garykom
 
гуру
22.03.16
22:12
(33) там "Родитель" легко может быть пустое в случае когда 1-е условие выполнилось а второе нет

а дальше мы этого пустого пытаемся Гр.УстановитьАтрибут("Родитель",Родитель);
39 Scandsv
 
22.03.16
22:12
(с) Никогда не говори ВСЕГДА
40 Злопчинский
 
22.03.16
22:12
Код ваще мутный
И в целом и в частностях

Следует
1. Найти группу по Подчинение
2. Создать группу если не найдена
3. Запомнить ссылку группы
4. Найти элемент (если не найден элемент то создать при необходимости)
5. В элемент присвоить родителя из п.3

ВСЕ
41 Scandsv
 
22.03.16
22:13
(33) А вот как раз пустое, насколько я помню и прокатит
42 Злопчинский
 
22.03.16
22:13
(38)  я на это уже обратил внимание выше и при том коде что написан родитель может вообще из пред. Строки унаследоватьс
43 Scandsv
 
22.03.16
22:13
(40) Соглашусь - мутный
44 MathaiShung
 
22.03.16
22:14
(36) Я это знаю, я сам загружаемую в ТЗ таблицу делал
45 Злопчинский
 
22.03.16
22:15
(44)  короче склифасовский
Врубай скайп и тимвьювер
Будем писать под диктовку
Скайп zlopun
46 Garykom
 
гуру
22.03.16
22:15
(41) да ну?


Процедура ПроверкаСообщить()
Сообщить(""+ТипаПустаяПеремнная);
КонецПроцедуры



где ТипаПустаяПеремнная нигде выше не присваивается
47 Злопчинский
 
22.03.16
22:16
Я сегодня добрвй
Приехал с Родины
48 MathaiShung
 
22.03.16
22:18
(40) Правильно, именно такую логику я хочу реализовать.
49 Scandsv
 
22.03.16
22:18
(46) не присвоенная переменная и пустая ссылка - это чуть разные понятия, или я не прав?
50 Злопчинский
 
22.03.16
22:18
(48) а написал хрень полную
51 Scandsv
 
22.03.16
22:18
(47) А где Родина?
52 Garykom
 
гуру
22.03.16
22:19
(49) Так у него выше Родитель скорее всего не элемент нужного справочника
53 Злопчинский
 
22.03.16
22:20
(51) Брест
54 MathaiShung
 
22.03.16
22:22
(45) Да ладно, сам уже додумаю, спасибо. Тут много чего посоветовали - буду исправлять...
55 Scandsv
 
22.03.16
22:23
(54) Удачи.
(53) Хорошего настроения на долго
56 Злопчинский
 
22.03.16
22:28
Спр = СоздатьОбъект("Справочник.Номенклатура");
//
Пока ТЗ.ПолучитьСтроку()=1 Цикл

   Подчинение = ТЗ.ПолучитьЗначение(НомСтр,1);
   Код = ТЗ.ПолучитьЗначение(НомСтр,2);
   Наименование = ТЗ.ПолучитьЗначение(НомСтр,3);

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

   Если Спр.НайтиПоКоду(Код,0)=0 Тогда
      Сообщить("ПРОПУЩЕНО: не найден элемент по коду: "+Код);
      Продолжить;
   КонецЕсли;
   Спр.Родитель = Родитель;
   Спр.Записать();
КонецЦикла;
57 MathaiShung
 
23.03.16
19:51
(10) (56) Нет, не так. Дело в том, что я неправильно ответил на (40) (невнимательно прочитал) - у меня логика на самом деле другая.
1. Проверить по коду элементов в ТЗ существуют ли они в Справочнике.
Если НЕТ:
2.Создать новые группы (т.к. новых товаров я в ТЗ не добавлял) и присвоить им Код и Наименование из ТЗ.
3. Найти в Справочнике группы по коду в колонке Подчинение из ТЗ, определить их как Родитель(находить Родителя нужно только после создания новых Групп (т.к. они тоже будут являться Родителем для др. элементов) - потому он у меня и определяется внутри условия).
Если ДА:
4. Найти в Справочнике элементы по коду в колонке Код из ТЗ и присвоить новые Наименование и Родителя.
58 Злопчинский
 
23.03.16
21:00
(57) Описанная логика кривая, ибо
1. Проверить по коду элементов в ТЗ существуют ли они в Справочнике.
Если ДА:
4. Найти в Справочнике элементы по коду в колонке Код из ТЗ и присвоить новые Наименование и Родителя.

из п.1 "Проверить по коду элементов в ТЗ существуют ли они в Справочнике." и из п.4 "Найти в Справочнике элементы по коду в колонке Код из ТЗ" - это одно и то же, т.к. проверить без поиска нельзя.

вдобавок в п.4 в случае ЕСЛИ ДА - "новые наименование и родитель - ОНИ ОТКУДА? они - неопределены...

У вас проблемы с алгоритмикой...
59 MathaiShung
 
23.03.16
21:43
(58) С алгоритмикой как раз всё хорошо, скорее проблемы с правильным пониманием работы методов - когда что на чём позиционируется, поэтому начал мудрить с этим поиском.
Сейчас переделал - всё работает как надо:
Процедура МодификацияСправочника()
    Спр=СоздатьОбъект("Справочник.Номенклатура");
    Спр.ВыбратьЭлементы();
    ТЗ.ВыбратьСтроки();
    НомСтр=0;
    Пока ТЗ.ПолучитьСтроку()=1 Цикл
        НомСтр=НомСтр+1;
        Подчинение=ТЗ.ПолучитьЗначение(НомСтр,1);
        Код=ТЗ.ПолучитьЗначение(НомСтр,2);
        Наименование=ТЗ.ПолучитьЗначение(НомСтр,3);
        Если Спр.НайтиПоКоду(Код,0)=0 Тогда
            Спр.НоваяГруппа();
            Спр.УстановитьАтрибут("Код",Код);
            Спр.УстановитьАтрибут("Наименование",Наименование);
            Спр.Записать();    
        Иначе
            Спр.УстановитьАтрибут("Наименование",Наименование);
            Спр.Записать();    
        КонецЕсли;
        Если Спр.НайтиПоКоду(Подчинение,0)=1 Тогда
            Родитель=Спр.ТекущийЭлемент();
        Иначе
            Родитель=ПолучитьПустоеЗначение("Справочник.Номенклатура")
        КонецЕсли;
        Если Спр.НайтиПоКоду(Код,0)=1 Тогда
            Спр.Родитель=Родитель;
            Спр.Записать();
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры
60 MathaiShung
 
23.03.16
21:46
+ (59) Ну и ошибка была в пустом значении поля Подчинение у групп 1-го уровня в ТЗ
61 Злопчинский
 
23.03.16
22:26
(60) Попробуй нижележащий код. Он, по идее, должен давать точно тот же результат что и твой (это и есть твой код, причесанный):

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

если все норм будет - тогда втыкай в код.. ;-)
успкхов!
62 MathaiShung
 
23.03.16
22:43
(61) Да, вроде всё также, хотя пока не совсем понятно почему. Спасибо, буду разбираться...
63 2S
 
23.03.16
22:48
все не читал, лень
сходу - группа?
64 Злопчинский
 
23.03.16
22:51
(62) потому что тривиальная программистская логика
код
        Если Спр.НайтиПоКоду(Подчинение,0)=1 Тогда
            Родитель = Спр.ТекущийЭлемент();
        Иначе
            Родитель = ПолучитьПустоеЗначение("Справочник.Номенклатура")
        КонецЕсли;

никак НЕ СВЯЗАН с предыдущим куском кода. Сдвигаем этот код вверх, сразу после чтения данных из строки ТЗ

получается далее (кусок кода который РАЗДЕЛЯЛ этот код ушел наверх) осталось:

        Если Спр.НайтиПоКоду(Код,0)=0 Тогда
            Спр.НоваяГруппа();
            Спр.УстановитьАтрибут("Код",Код);
            Спр.УстановитьАтрибут("Наименование",Наименование);
            Спр.Записать();    
        Иначе
            Спр.УстановитьАтрибут("Наименование",Наименование);
            Спр.Записать();    
        КонецЕсли;
        Если Спр.НайтиПоКоду(Код,0)=1 Тогда
            Спр.Родитель=Родитель;
            Спр.Записать();
        КонецЕсли;
65 Злопчинский
 
23.03.16
22:52
эти два блока если отрабатывают одно и то же, объединяем

        Если Спр.НайтиПоКоду(Код,0)=0 Тогда
            Спр.НоваяГруппа();
            Спр.УстановитьАтрибут("Код",Код);
            Спр.УстановитьАтрибут("Наименование",Наименование);
            Спр.Записать();    
        Иначе
            Спр.Родитель=Родитель;
            Спр.Записать();
Спр.УстановитьАтрибут("Наименование",Наименование);
            Спр.Записать();    
        КонецЕсли;
66 Злопчинский
 
23.03.16
22:53
Упрощаем

Если Спр.НайтиПоКоду(Код,0)=0 Тогда
            Спр.НоваяГруппа();
            Спр.УстановитьАтрибут("Код",Код);
            Спр.УстановитьАтрибут("Наименование",Наименование);
            Спр.Записать();    
        Иначе
            Спр.Родитель=Родитель;
           Спр.УстановитьАтрибут("Наименование",Наименование);
            Спр.Записать();    
        КонецЕсли;
67 Злопчинский
 
23.03.16
22:54
общий код выносим за пределы если

Если Спр.НайтиПоКоду(Код,0)=0 Тогда
   Спр.НоваяГруппа();
   Спр.УстановитьАтрибут("Код",Код);
Иначе
   Спр.Родитель=Родитель;
КонецЕсли;

Спр.УстановитьАтрибут("Наименование",Наименование);
Спр.Записать();
68 Злопчинский
 
23.03.16
22:55
далее думаю понятно...
заметь - тупой рефакторинг кода, даже без вникания в логику. по простым формальным признакам.
69 MathaiShung
 
23.03.16
23:06
(68) Да, да, всё правильно, я уже повтыкал в код и сам понял, то о чём Вы выше написали.
70 Злопчинский
 
24.03.16
00:27
(69) Вот видишь - надо всего лишь подумать... а не тыкать клаву в диком митусении ;-)

Успехов!
71 MathaiShung
 
25.03.16
20:08
Спасибо. Только в (61) не хватает Спр.Родитель=Родитель внутри Если Спр.НайтиПоКоду(Код,0) = 0 - это меня и смутило сразу, а потом уже и про рефакторинг заметил. Если не устанавливать родителя при создании новых групп, потом они не присвоятся. Ведь Иначе отрабатывает в этом же цикле ещё не созданные элементы.
72 Злопчинский
 
26.03.16
00:02
(71) согласен, правильное замечание, тогда судя по всему - еще проще.. ;-)

    Спр = СоздатьОбъект("Справочник.Номенклатура");
    ТЗ.ВыбратьСтроки();
    Пока ТЗ.ПолучитьСтроку()=1 Цикл
        
        НомСтр = ТЗ.НомерСтроки;
        Подчинение = ТЗ.ПолучитьЗначение(НомСтр,1);
        Код = ТЗ.ПолучитьЗначение(НомСтр,2);
        Наименование = ТЗ.ПолучитьЗначение(НомСтр,3);
        
        Если Спр.НайтиПоКоду(Подчинение,0)=1 Тогда
            Родитель = Спр.ТекущийЭлемент();
        Иначе
            Родитель = ПолучитьПустоеЗначение("Справочник.Номенклатура")
        КонецЕсли;
        
        Если Спр.НайтиПоКоду(Код,0) = 0 Тогда
            Спр.НоваяГруппа();
            Спр.Код = Код;
        КонецЕсли;
        Спр.Родитель = Родитель;
        Спр.Наименование = Наименование;
        Спр.Записать();    
        
    КонецЦикла;
Я не хочу быть самым богатым человеком на кладбище. Засыпать с чувством, что за день я сделал какую-нибудь потрясающую вещь — вот что меня интересует. Стив Джобс