Имя: Пароль:
1C
1С v8
Поиск одинаковых ценников в ТЧ
0 Валидатор
 
01.08.14
14:26
Есть табличная часть с номенклатурой, ценой и тд. Нужно сделать цикл, в котором проверялось бы следующее: если в табличной части одинаковая номенклатура, то смотреть ее ценник, если ценник разный, выдавать ошибку, если одинаковый то идти дальше
1 Валидатор
 
01.08.14
14:27
можно на номер строки зацепиться но мне не нравится эта идея
2 Ёпрст
 
01.08.14
14:29
смотреть её ценник - это что за зверь такой ?
3 Timon1405
 
01.08.14
14:29
здесь попкорн сразу выдают или сходить успею?
4 Валидатор
 
01.08.14
14:30
(3) у мамки твоей попкорн я оставил
5 Luhtas
 
01.08.14
14:32
(2) Видимо имеется ввиду цена номенклатуры.
6 Валидатор
 
01.08.14
14:32
То есть если так:
стул 50р
Стул 150р

такой вариант должен выдать ошибку, а если
Стул 50р
Стул 50р, то все норм
7 Fish
 
01.08.14
14:37
(6) Так а что конкретно не получается?
8 Валидатор
 
01.08.14
14:38
(7) да я не могу придумать как бы их сравнить, ладно если 2 строки, а если у меня n-количество строк, как я их буду сравнивать?
9 Ёпрст
 
01.08.14
14:42
получаешь список уникальной номенклатуры (тупо через выгрузить колонку и свернуть), далее через цикл по уникальным записям по номенклатуре выгружаешь во временную строки с отбором по этой номенклатуре и сворачиваешь эту временную тз по номенклатуре и цене, ежели количество строк в ней будет>1 - то это то, что тебе нужно

Всё это можно сделать и в запросе, поместив ТЧ во временную тз в запросе и ..собственно сам запрос с группировкой +количество()...
10 IVT_2009
 
01.08.14
14:43
код 1с 77 примерно аналогичная задача

функция тест_вернутьСправочникСинергия()
    вт = создатьОбъект("таблицаЗначений");
    вт.новаяКолонка("код");
    вт.новаяКолонка("скю");
    запрос = создатьОбъект("запрос");
    текстЗапроса = "
    |спр     = справочник.номенклатура.текущийЭлемент;
    |товар     = справочник.номенклатура.наименование;
    |код     = справочник.номенклатура.код;
    |грпПрв = справочник.номенклатура.производитель.группаКонтрагента;
    |группировка код без групп;
    |условие(грпПрв = ВыбГрпПрвРП2 );";
    запрос.выполнить(текстЗапроса);
    пока запрос.группировка(1) = 1 цикл
        если врег(лев(запрос.товар,2)) = "ЯЯ" тогда
            продолжить;
        конецЕслИ;
        вт.новаяСтрока();
        вт.код    = вернутьЗначениеСвойства("СвойстваНоменклатуры",запрос.спр,"кодСинергия");
        вт.скю  = уп(запрос.товар);
    конецЦикла;
    вт.свернуть("код,скю","");    
    вт.сортировать("скю,-код");
    вт.новаяКолонка("метка");
    //*** есть название , есть код
    //*** последовательно переберем тз
    //*** берем первый товар и делаем его опорным , сревним со следующим , если он
    //*** совпал то проверим на наличие кода.
    //*** если нет кода то ставим пометку удаления.
    опТовар = вт.получитьЗначение(1,"скю");
    вт.выбратьСтроки();
    ъ = 0;
    пока вт.получитьСтроку()=1 цикл
        ъ = ъ + 1;
        если ъ>1 тогда //***первый элемент пропускаем = он равен сам себе )))
            если вт.скю = опТовар тогда
                //если стрДлина(вт.код)=0 тогда //***позиция совпала и код пустой - данную позицию удалим
                    вт.установитьЗначение(ъ,"метка",1);
                //конецЕсли;    
            иначе
                опТовар = вт.скю;
            конецЕсли;    
        конецЕсли;    
    конецЦикла;
    для Индекс = -вт.КоличествоСтрок() по -1 цикл
        вт.ПолучитьСтрокуПоНомеру(-Индекс);
        если вт.метка = 1 тогда
            вт.УдалитьСтроку();
        конецЕсли;
    конецЦикла;    
    возврат вт;
конецФункции    //функция тест_вернутьСправочникСинергия()
11 Фокусник
 
01.08.14
14:48
(8) "ладно если 2 строки, а если у меня n-количество строк, как я их буду сравнивать?"

Можно так:
ТЗ1 = ТЧ.Выгрузить().Свернуть("Номенклатура, Цена");
ТЗ2 = ТЧ.Выгрузить().Свернуть("Номенклатура");

Если количество строк в ТЗ1 и в ТЗ2 РАЗНОЕ, значит ошибка.

Далее можно вывести сообщения по ТЗ1 по тем номенклатурам, которых >1 попало в ТЗ1
12 salvator
 
01.08.14
14:50
Таблицу в запрос, итоги по номенклатуре и цене. Далее в цикле проходишь по уровням дерева, если количество() в выборке 2-го уровня больше 1, то ошибка.
13 Валидатор
 
01.08.14
14:50
(11) ценники тоже сворачиваются, допустим у одного цена 50 у другого 250, он сворачивает в 300 жто числовое поле
14 Валидатор
 
01.08.14
14:50
СоответствиеЦен = Новый Соответствие;
      Для Каждого СтрокаТЧ ИЗ ТТН.Товары Цикл
          ТекЦена = СоответствиеЦен.Получить(СтрокаТЧ.Номенклатура);
          Если ТекЦена = Неопределено Тогда //еще не задано первое значение
              СоответствиеЦен.Вставить(СтрокаТЧ.Номенклатура, СтрокаТЧ.Цена);
          ИначеЕсли ТекЦена <> СтрокаТЧ.Цена Тогда
              Сообщить("Нельзя создавать ТТН по заказам с разными ценами");
              Возврат ?! //какую функцию использовать на этом месте чтобы летела ошибка и код далее не выполнялся?
          КонецЕсли;
      КонецЦикла;
15 ale-sarin
 
01.08.14
14:51
(11) Если не запросом, то тогда уж выгрузить в ТЗ, добавить колонку-число, заполнить ее единицами
Потом Свернуть("Номенклатура, Цена", "НоваяКолонка")
Ищем где НоваяКолонка больше 1.
16 Фокусник
 
01.08.14
14:52
(13) Если так: .Свернуть("Номенклатура, Цена"), то НЕ сворачивает, это же поля для группировки, прочитай СП ;)
17 Фокусник
 
01.08.14
14:53
(15) не соответствует условию в (6)
18 ale-sarin
 
01.08.14
14:56
(17) ааа, ну да.
Тогда можно свернуть перед добавлением колонки. А потом (15).
Но, конечно, я бы запросом сделал.
19 ale-sarin
 
01.08.14
14:59
(14) А где этот код выполняется?
20 jsmith
 
01.08.14
15:00
Процедура ПроверкаСтрок()
    ТЗ = Объект.Товары.Выгрузить();
    Для Каждого Строка Из ТЗ Цикл
        Строки = НайтиСтроки(Строка.Номенклатура, ТЗ);
        Валидность = ПроверитьВалидность(МассивСтрок);
        Если Не Валидность Тогда
            СообщитьОНевалидности(МассивСтрок);
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры;

Функция НайтиСтроки(Товар, ТЗ)

    Отбор = Новый Структура("Номенклатура", Товар);
    МассивСтрок = ТЗ.НайтиСтроки(Отбор);
    Возврат МассивСтрок;

КонецФункции

Функция ПроверитьВалидность(МассивСтрок)
    Валидность = Истина;
    Цена = МассивСтрок[0].Цена;
    Для Каждого Строка Из МассивСтрокЦикл
        Если Строка.Цена <> Цена Тогда
            Валидность = Ложь;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    Возврат Валидность;
КонецФункции

Процедура СообщитьОНевалидности(МассивСтрок)
    Сообщить("Обнаружены разные цены по товару " + Строка.Номенклатура);
    Для Каждого Строка Из МассивСтрок Цикл
        Сообщить("По строке " + Строка.НомерСтроки + ": " + Строка.Цена);
    КонецЦикла;
КонецПроцедуры
21 Валидатор
 
01.08.14
15:00
(19) на сервере
22 ale-sarin
 
01.08.14
15:01
(21) Откуда вызывается? Переда записью? Или кнопка для проверки?
23 Валидатор
 
01.08.14
15:01
(21) кнопка для проверки, при нажатии которой все это дело делается в функции на сервере, а потом открывается на клиенте
24 Валидатор
 
01.08.14
15:03
dct gj[jle gjyzk
25 Валидатор
 
01.08.14
15:03
все, походу понял
26 Ёпрст
 
01.08.14
15:03
(20) лучше не прервать, а сразу Возврат Ложь.. лепить, красившее как-то
27 Валидатор
 
01.08.14
15:04
&НаКлиенте
Процедура Команда1(Команда)
     Документ = НаСервере();
     Если НЕ Документ = Неопределено Тогда
         Структура = Новый СТруктура("Ключ",Документ);
         ОткрытьФорму("Документ.ТТН.Форма.ФормаДокумента",Структура);
     Иначе
         Сообщить("Нельзя создавать ТТН по заказам с разными ценами номенклатуры");
     КонецЕсли;
КонецПроцедуры
28 Валидатор
 
01.08.14
15:04
(26) возвращаю там теперь просто неопределено)
29 ale-sarin
 
01.08.14
15:04
(23) Я бы не прекращал поиск других кривых строк из-за первой найденной. Нашел бы все несовпадения, вернул их на клиент, и сообщил пользователю.
30 Валидатор
 
01.08.14
15:14
Новая проблема:
Для Каждого СтрокаТЧ ИЗ ТТН.Товары Цикл
          ТекЦена = СоответствиеЦен.Получить(СтрокаТЧ.Номенклатура);
          Если ТекЦена = Неопределено Тогда //еще не задано первое значение
              СоответствиеЦен.Вставить(СтрокаТЧ.Номенклатура, СтрокаТЧ.Цена);
          ИначеЕсли ТекЦена <> СтрокаТЧ.Цена Тогда
              Возврат Неопределено;
          КонецЕсли;
          
      КонецЦикла;
В случае когда возвращается неопределено, то результатом функции будет неопределно, но если условие не попадает туда где Возврат Неопределно, то все равно функция возвращает неопределено, как быть7
31 ale-sarin
 
01.08.14
15:17
(30) После цикла сделайте
Возврат "Все нормально";
32 Валидатор
 
01.08.14
15:18
СоответствиеЦен = Новый Соответствие;
    
      Для Каждого СтрокаТЧ ИЗ ТТН.Товары Цикл
          ТекЦена = СоответствиеЦен.Получить(СтрокаТЧ.Номенклатура);
          Если ТекЦена = Неопределено Тогда //еще не задано первое значение
              СоответствиеЦен.Вставить(СтрокаТЧ.Номенклатура, СтрокаТЧ.Цена);
          ИначеЕсли ТекЦена <> СтрокаТЧ.Цена Тогда
              Возврат Неопределено;
          Иначе
              ТТН.Записать();
              Возврат ТТН.Ссылка;
          КонецЕсли;
          
      КонецЦикла;