Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: В чем ошибка условия? 1С 7.70.003 торговля склад для Украины?
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 > Программисту > Программирование в 1С Предприятие 7.7
ZUBR
Здравствуйте. Даю фрагмент сырого кода отчета по результатам работы сотрудников. Никак не пойму, почему не работает условие.

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

КонецПроцедуры


Строки
// Сообщить("Сотр:"+ ТЗ.Сотрудник);
                         //  Сообщить("Инж:"+ Расх.Инженер);
                         // Сообщить("След. накл");

и строку
//  Иначе К=10;


я вставлял с целью диагностики проблемы. Пришел к выводу, что условие
 Если ТЗ.Сотрудник = Расх.Инженер Тогда
не выполняется , когда оно должно выполняться. Реквизит Инженер в РасходныхНакладных берется из Справочника Сотрудники. Оттуда же берется и значение ТЗ. Сотрудник. Почему же при совпадении этих значений программа считает, что они не равны?! Программа в таблицу записывает К= 10. А если закомментировать тестовую строку Иначе К=10, тогда в столбце ТЗ.КолСис вообще ничего не прописывается. То есть, условие железно должно выполняться, а программа ведет себя так, вроде оно не выполняется. Уже сутки ломаю голову. Спасибо!
andrew76
Добрый вечер !

Скорее всего условие не выполняется потому что в операции сравнения участвуют типы Строковый и Ссылочный.

ТЗ.Сотрудник = Спр.Наименование; //Тип Строка
Документ.РасходнаяНакладная.Инженер //Тип Ссылочный (ссылка на Справочник.Сотрудники)

Поэтому код надо переписать так в последней строке фрагмента:


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

ZUBR
andrew76 @ Сегодня, 18:57 необходимо зарегистрироваться для просмотра ссылки , НетТо же самое(((
Макс1С
Это, конечно, не решение описанной ошибки, но решения для достижения результата - ТЗ со списком у какого из инженеров сколько документов. Возможно кто-то поправит, не помню есть ли в 7.7 в запросе функция по аналогии с "Количество различных", кажется нет, поэтому складываю количество в обработке запроса.

Запрос = СоздатьОбъект("Запрос");
    ТекстЗапроса =
    "//{{ЗАПРОС(Сформировать)
    |Период с ВыбНачПериода по ВыбКонПериода;
    |Автор = Документ.РасходнаяНакладная.Автор;
    |ТекущийДокумент = Документ.РасходнаяНакладная.ТекущийДокумент;
    |Группировка Автор;
    |Группировка ТекущийДокумент;
    |"//}}ЗАПРОС
;

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

        К = 0;
        Пока Запрос.Группировка(2) = 1 Цикл
            К = К + 1;
        КонецЦикла;
        
        ТЗ.КолСис = К;
    КонецЦикла;


а в целом в такой ситуации, когда непонятно почему так происходит - отладчик в помощь, точку останова на "Если ТЗ.Сотрудник = Расх.Инженер" и смотреть что в одном поле и в другом. Но в первую очередь - согласен с предыдущим оратором - типы разные, строка сравнивается со справочником. Как варик - привести всё к строкам:
ТЗ.Сотрудник = Спр.Наименование;
//////
......
//////
Если ТЗ.Сотрудник = Расх.Инженер.Наименование Тогда
1Cv77
ZUBR @ Сегодня, 18:11 необходимо зарегистрироваться для просмотра ссылки ,
Доброго времени суток.

Прошу прощения за глупый вопрос:
А в Отладчике, если остановить процедуру на:
Если ТЗ.Сотрудник = Расх.Инженер Тогда


Что выдает по "ТЗ.Сотрудник" и "Расх.Инженер Тогда" ???
Какие значения?
ZUBR
1Cv77 @ Сегодня, 21:26 необходимо зарегистрироваться для просмотра ссылки ,
я вставлял в это место программы Сообщить. Значения переменных одинаковые. Я об этом писал в стартовом посте.

Макс1С @ Сегодня, 21:23 необходимо зарегистрироваться для просмотра ссылки , спасибо за помощь! В Вашем варианте

ТЗ.Сотрудник = Спр.Наименование;
//////
......
//////
Если ТЗ.Сотрудник = Расх.Инженер.Наименование Тогда

все заработало! Век живи, век учись. Я бы не додумался. Если бы Вы еще объяснили, причем тут Наименование до Инженера.) Инженер - это же реквизит Расходной накладной. Идентификатор. Мне не понятно(
Макс1С
ZUBR @ Вчера, 23:13 необходимо зарегистрироваться для просмотра ссылки ,
во-первых: Сообщить() возвращает строковое представление, для справочников это по-умолчанию наименование.
во-вторых: без отладчика точно сказать по куску кода невозможно, как писали выше.
в 3-х: .Наименование - просто реквизит справочника(надеюсь Сотрудники)

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

Поэтому сравнивать, конечно, лучше ссылки и правильный код тогда:
ТЗ.Сотрудник = Спр.ТекущийЭлемент();
//////
......
//////
Если ТЗ.Сотрудник = Расх.Инженер Тогда

, проверив отладчиком типы, или сделать запросом.



без отладчика можно проверить так:

  Сообщить("Инж:"+ Расх.Инженер.Вид());
  Сообщить("Сотр:"+ ТЗ.Сотрудник.Вид());
andrew76
Попробуйте такой вариант , можно его еще укоротить...
Это так , для наглядности.

Запрос = СоздатьОбъект("Запрос");
    ТекстЗапроса =
    "//{{ЗАПРОС(Сформировать)
    |Период с ВыбНачПериода по ВыбКонПериода;
    |Инженер = Документ.РасходнаяНакладная.Инженер;
    |ТекущийДокумент = Документ.РасходнаяНакладная.ТекущийДокумент;
    |Группировка ТекущийДокумент;
    |"//}}ЗАПРОС
;

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

ТЗ.Свернуть("Инженер","КолСис");    //Подсчет итогов по каждому из инженеров


Еще раз посмотрел первый пост ветки.Не совсем верный код.
mut
Подсчет делается внутри перебора элементов справочника, нет смысла писать сотрудника в таблицу и потом сравнивать с таблицей.
Нужно сделать выборку накладных по текущему элементу справочника, потом добавить все в строку таблицы.

Спр.ВыбратьЭлементы();
      Пока Спр.ПолучитьЭлемент()=1 Цикл
            
          К = 0;
           Расх.ВыбратьДокументы(НачДата,КонДата);
          
      Пока Расх.ПолучитьДокумент()=1 Цикл
          
          Если Спр.ТекущийЭлемент() = Расх.Инженер Тогда
                К=К+1;
              КонецЕсли;
              
            КонецЦикла;

         ТЗ.НоваяСтрока();
          ТЗ.Сотрудник = Спр.Наименование;
      ТЗ.КолСис = К;

    КонецЦикла;
andrew76
Цитата(mut @ 16.09.19, 14:07) необходимо зарегистрироваться для просмотра ссылки
Подсчет делается внутри перебора элементов справочника, нет смысла писать сотрудника в таблицу и потом сравнивать с таблицей.
Нужно сделать выборку накладных по текущему элементу справочника, потом добавить все в строку таблицы.


Этт точно !.Я с Вами совершенно согласен !


ТЗ = СоздатьОбъект("ТаблицаЗначений"); 
ТЗ.НоваяКолонка ("Инженер");
ТЗ.НоваяКолонка ("КолСис");   // количество систем
    
Расх.ВыбратьДокументы(НачДата,КонДата);
          
Пока Расх.ПолучитьДокумент()=1 Цикл
    ТЗ.НоваяСтрока();
    ТЗ.Инженер=Расх.Инженер;
    ТЗ.КолСис=1;
КонецЦикла;

ТЗ.Свернуть("Инженер","КолСис");    //Подсчет итогов по каждому из инженеров
ZUBR
Всем большое спасибо за помощь. Мне до вас далеко))). Но нужно стремиться! Думаю, последний вариант для меня будет самым эффективным. Все оказалось гораздо проще!
andrew76
ZUBR @ Сегодня, 18:59 необходимо зарегистрироваться для просмотра ссылки ,

Не за что,вариант с запросом (моё сообщение Сегодня, 13:17) и вариант
с перебором документов (моё сообщение Сегодня, 15:43)-они оба аналогичны.
Удачи !


Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.