Заказы на доработку 1С (сервис удаленной работы)

Хранилище

База знаний
Неназначенных незавершенных заказов: 2, свеженьких 1
Бесплатные отчеты, обработки, конфигурации, внешние компоненты для 1С Статьи, описание работы, методики по работе с 1С

Здравствуйте, гость ( Вход | Зарегистрироваться )



> В чем ошибка условия? 1С 7.70.003 торговля склад для Украины?          
ZUBR Подменю пользователя
сообщение 15.09.19, 16:55
Сообщение #1

Завсегдатай
****
Группа: Пользователи
Сообщений: 229
Из: Київ
Спасибо сказали: 5 раз
Рейтинг: 3

Здравствуйте. Даю фрагмент сырого кода отчета по результатам работы сотрудников. Никак не пойму, почему не работает условие.

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

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


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

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


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

andrew76 Подменю пользователя
сообщение 15.09.19, 17:57
Сообщение #2

Оратор
*****
Группа: Пользователи
Сообщений: 378
Из: Казахстан
Спасибо сказали: 39 раз
Рейтинг: 39

Добрый вечер !

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

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

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


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


ZUBR Подменю пользователя
сообщение 15.09.19, 19:11
Сообщение #3

Завсегдатай
****
Группа: Пользователи
Сообщений: 229
Из: Київ
Спасибо сказали: 5 раз
Рейтинг: 3

andrew76 @ Сегодня, 18:57 * , НетТо же самое(((

Макс1С Подменю пользователя
сообщение 15.09.19, 20:23
Сообщение #4

Завсегдатай
Иконка группы
Группа: Местный
Сообщений: 178
Из: Днепр
Спасибо сказали: 61 раз
Рейтинг: 57.6

Это, конечно, не решение описанной ошибки, но решения для достижения результата - ТЗ со списком у какого из инженеров сколько документов. Возможно кто-то поправит, не помню есть ли в 7.7 в запросе функция по аналогии с "Количество различных", кажется нет, поэтому складываю количество в обработке запроса.

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

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

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


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

Спасибо сказали: ZUBR,

1Cv77 Подменю пользователя
сообщение 15.09.19, 20:26
Сообщение #5

Завсегдатай
****
Группа: Пользователи
Сообщений: 195
Из: Украина, Мелитополь
Спасибо сказали: 61 раз
Рейтинг: 0

ZUBR @ Сегодня, 18:11 * ,
Доброго времени суток.

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


Что выдает по "ТЗ.Сотрудник" и "Расх.Инженер Тогда" ???
Какие значения?

ZUBR Подменю пользователя
сообщение 15.09.19, 22:13
Сообщение #6

Завсегдатай
****
Группа: Пользователи
Сообщений: 229
Из: Київ
Спасибо сказали: 5 раз
Рейтинг: 3

1Cv77 @ Сегодня, 21:26 * ,
я вставлял в это место программы Сообщить. Значения переменных одинаковые. Я об этом писал в стартовом посте.

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

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

все заработало! Век живи, век учись. Я бы не додумался. Если бы Вы еще объяснили, причем тут Наименование до Инженера.) Инженер - это же реквизит Расходной накладной. Идентификатор. Мне не понятно(

Макс1С Подменю пользователя
сообщение 15.09.19, 23:56
Сообщение #7

Завсегдатай
Иконка группы
Группа: Местный
Сообщений: 178
Из: Днепр
Спасибо сказали: 61 раз
Рейтинг: 57.6

ZUBR @ Вчера, 23:13 * ,
во-первых: Сообщить() возвращает строковое представление, для справочников это по-умолчанию наименование.
во-вторых: без отладчика точно сказать по куску кода невозможно, как писали выше.
в 3-х: .Наименование - просто реквизит справочника(надеюсь Сотрудники)

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

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

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



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

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

Спасибо сказали: ZUBR,

andrew76 Подменю пользователя
сообщение 16.09.19, 10:17
Сообщение #8

Оратор
*****
Группа: Пользователи
Сообщений: 378
Из: Казахстан
Спасибо сказали: 39 раз
Рейтинг: 39

Попробуйте такой вариант , можно его еще укоротить...
Это так , для наглядности.

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

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

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


Еще раз посмотрел первый пост ветки.Не совсем верный код.

Спасибо сказали: ZUBR,

mut Подменю пользователя
сообщение 16.09.19, 11:07
Сообщение #9

Завсегдатай
****
Группа: Пользователи
Сообщений: 155
Из: Новая Каховка
Спасибо сказали: 108 раз
Рейтинг: 119.1

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

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

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

    КонецЦикла;

Спасибо сказали: ZUBR,

andrew76 Подменю пользователя
сообщение 16.09.19, 12:43
Сообщение #10

Оратор
*****
Группа: Пользователи
Сообщений: 378
Из: Казахстан
Спасибо сказали: 39 раз
Рейтинг: 39

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


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


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

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

Спасибо сказали: ZUBR,

ZUBR Подменю пользователя
сообщение 16.09.19, 15:59
Сообщение #11

Завсегдатай
****
Группа: Пользователи
Сообщений: 229
Из: Київ
Спасибо сказали: 5 раз
Рейтинг: 3

Всем большое спасибо за помощь. Мне до вас далеко))). Но нужно стремиться! Думаю, последний вариант для меня будет самым эффективным. Все оказалось гораздо проще!

Спасибо сказали: andrew76,

andrew76 Подменю пользователя
сообщение 16.09.19, 16:07
Сообщение #12

Оратор
*****
Группа: Пользователи
Сообщений: 378
Из: Казахстан
Спасибо сказали: 39 раз
Рейтинг: 39

ZUBR @ Сегодня, 18:59 * ,

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



Не нашли ответа на свой вопрос?
Зарегистрируйтесь и задайте новый вопрос.


Ответить Новая тема
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

RSS Текстовая версия Сейчас: 15.06.21, 9:08
1С Предприятие 8.3, 1С Предприятие 8.2, 1С Предприятие 8.1, 1С Предприятие 8.0, 1С Предприятие 7.7, Литература 1С, Общие вопросы по администрированию 1С, Методическая поддержка 1С - всё в одном месте: на Украинском 1С форуме!