Имя: Пароль:
1C
1С v8
ошибка в запросе?
0 Kurbash
 
30.05.14
09:17
Такая ситуация-есть внешняя обработка, на которой две ТЧ:
http://imgoo.ru/619628/fd3d/KJMtb2qb1jY/sX9suf.jpg
и вторая :
http://imgoo.ru/619628/fd46/EiSdB5xeKkU/y9asuf.jpg

данные в первую тч подбираю из базы проходной, признак входа-1 вход, 2 выход.
Хочу сделать по такому алгоритму-выбираю максимальное значение дат входа и выхода по табельному номеру из первой тч, пишу во вторую, строки которые выбрал удаляю. Делаю так:


запрос=новый запрос();
    запрос.Текст="ВЫБРАТЬ
                 |    а.номерстроки,
                 |    а.табном,
                 |    а.Фамилия,
                 |    а.Имя,
                 |    а.отчество,
                 |    а.датасобытия,
                 |    а.признаквхода
                 |ПОМЕСТИТЬ табл
                 |ИЗ
                 |    &состав КАК а
                 |;
                 |
                 |////////////////////////////////////////////////////////////////////////////////
                 |ВЫБРАТЬ
                 |    т.номерстроки,
                 |    МАКСИМУМ(т.датасобытия) КАК датасобытия
                 |ИЗ
                 |    табл КАК т
                 |ГДЕ
                 |    т.признаквхода = 1
                 |    И т.табном = &табном
                 |
                 |СГРУППИРОВАТЬ ПО
                 |    т.номерстроки
                 |;
                 |
                 |////////////////////////////////////////////////////////////////////////////////
                 |ВЫБРАТЬ
                 |    т1.номерстроки,
                 |    МАКСИМУМ(т1.датасобытия) КАК датасобытия
                 |ИЗ
                 |    табл КАК т1
                 |ГДЕ
                 |    т1.признаквхода = 2
                 |    И т1.табном = &табном
                 |
                 |СГРУППИРОВАТЬ ПО
                 |    т1.номерстроки";
             конеццикла;
запрос.УстановитьПараметр("Состав",состав.Выгрузить());
запрос.УстановитьПараметр("табном",стр.ТабНом);

результат=запрос.Выполнить().Выбрать();
пока результат.Следующий() цикл
т=сотрудники.Добавить();
т.ТабНом=результат.табном;

функия максимума не работает0выводятся все значения. где ошибся?
1 Kurbash
 
30.05.14
09:29
а, вот запрос поправил:

ВЫБРАТЬ
                 |    а.номерстроки,
                 |    а.табном,
                 |    а.Фамилия,
                 |    а.Имя,
                 |    а.отчество,
                 |    а.датасобытия,
                 |    а.признаквхода
                 |ПОМЕСТИТЬ табл
                 |ИЗ
                 |    &состав КАК а
                 |;
                 |
                 |////////////////////////////////////////////////////////////////////////////////
                 |ВЫБРАТЬ
                 |    т.номерстроки,т1.номерстроки,
                 |    МАКСИМУМ(т.датасобытия) КАК датасобытия,МАКСИМУМ(т1.датасобытия) КАК датасобытия1
                 |ИЗ
                 |    табл КАК т,табл КАК т1
                 |ГДЕ
                 |    т.признаквхода = 1 и т1.признаквхода = 2
                 |    И т.табном = &табном И т1.табном = &табном
                 |
                 |СГРУППИРОВАТЬ ПО
                 |    т.номерстроки,т1.номерстроки
2 Ymryn
 
30.05.14
09:33
На вскидку, ошибка в              
|СГРУППИРОВАТЬ ПО
|    т.номерстроки

Не свернет он при такой группировке, ну никак не свернет.
3 Kurbash
 
30.05.14
09:33
сам на это грешу, но без группировки не пускает, там же агрегатная функция используется
4 Ymryn
 
30.05.14
09:35
(3) угу, так ты же по табельному номеру максимум находишь. Сам написал. Почему же группируешь по номеру строки? :)
5 dmpl
 
30.05.14
09:37
(3) Так убери номер строки. Ну или максимум бери от него.
6 wendy
 
30.05.14
09:39
А где строка менеджер виртуальных таблиц????
7 Kurbash
 
30.05.14
09:40
(5)точно, можно же получить максимум номер строки и потом на нее спозиционироваться в ТЧ и удалить, так?:)
8 Ymryn
 
30.05.14
09:50
(7) Можно, но получишь фигню.
9 Ymryn
 
30.05.14
09:57
Несколько скорректировал запрос, чтобы он соответствовал тому, что считается описанием задачи (ну или тому как я её понял).

запрос=новый запрос();
запрос.Текст="ВЫБРАТЬ
             |    а.номерстроки,
             |    а.табном,
             |    а.Фамилия,
             |    а.Имя,
             |    а.отчество,
             |    а.датасобытия,
             |    а.признаквхода
             |ПОМЕСТИТЬ табл
             |ИЗ
             |    &состав КАК а
             |;
             |
             |////////////////////////////////////////////////////////////////////////////////
             |ВЫБРАТЬ
             |    ТаблицаДанных.табном КАК ТабельныйНомер,
             |    МАКСИМУМ(ВЫБОР
             |            КОГДА ТаблицаДанных.признаквхода = 1
             |                ТОГДА ТаблицаДанных.датасобытия
             |            ИНАЧЕ ДАТАВРЕМЯ(1, 1, 1)
             |        КОНЕЦ) КАК датаВхода,
             |    МАКСИМУМ(ВЫБОР
             |            КОГДА ТаблицаДанных.признаквхода = 2
             |                ТОГДА ТаблицаДанных.датасобытия
             |            ИНАЧЕ ДАТАВРЕМЯ(1, 1, 1)
             |        КОНЕЦ) КАК датаВыхода
             |ИЗ
             |    табл КАК ТаблицаДанных
             |
             |СГРУППИРОВАТЬ ПО
             |    ТаблицаДанных.табном";

Итогом запроса является таблица - Табельный номер, Дата входа (макс), Дата выхода (макс) для соответствующего табельного номера. С номером строки у тебя будет большая проблема, ибо ты используешь промежуточную таблицу, где строк по указанному сотруднику несколько. Причем строка с максимумом даты входа и строка с максимум даты выхода - это две разные строчки. Планируется удалять именно эти строчки содержащие максимум или все строчки по данному табельному номеру?
10 Kurbash
 
30.05.14
09:57
сделал так:


    запрос=новый запрос();
    запрос.Текст="ВЫБРАТЬ
                 |    а.номерстроки,
                 |    а.табном,
                 |    а.Фамилия,
                 |    а.Имя,
                 |    а.отчество,
                 |    а.датасобытия,
                 |    а.признаквхода
                 |ПОМЕСТИТЬ табл
                 |ИЗ
                 |    &состав КАК а
                 |;
                 |
                 |////////////////////////////////////////////////////////////////////////////////
                 |ВЫБРАТЬ
                 |    МИНИМУМ(т.номерстроки) КАК номстр,
                 |    МИНИМУМ(т1.номерстроки) КАК номстр1
                 |ИЗ
                 |    табл КАК т,
                 |    табл КАК т1
                 |ГДЕ
                 |    т.признаквхода = 1
                 |    И т1.признаквхода = 2
                 |    И т.табном = &табном
                 |    И т1.табном = &табном";
             конеццикла;
запрос.УстановитьПараметр("Состав",состав.Выгрузить());
запрос.УстановитьПараметр("табном",стр.ТабНом);

результат=запрос.Выполнить().Выбрать();
пока результат.Следующий() цикл
ст=состав[результат.номстр-1];
ст1=состав[результат.номстр1-1];
сообщить(""+ст.ДатаСобытия+"/"+ст.ПРизнакВхода+"|||"+ст1.ДатаСобытия+"/"+ст1.ПРизнакВхода);
состав.Удалить(результат.номстр-1);
состав.Удалить(результат.номстр1-1);

конеццикла;    

работает правда только с одной строчкой....

(8)-по другому никак
11 Kurbash
 
30.05.14
09:58
(9)только максимум
12 Kurbash
 
30.05.14
10:02
(9) к тому же а если вход был а выхода не было и наоборот?
13 Ymryn
 
30.05.14
10:03
(11) тогда по результатам запроса в (9), осуществляешь поиск по таблице по сочетанию полей(Табномер, датасобытия, признаквхода) 2 раза, для каждого признака и удаляешь. Получать номер строки запросом для удаления нецелесообразно, ты все равно не сможешь удалить две строчки сразу, а после первого удаления номера строк изменяться. Это если отойти от того, что запрос в (10) получает далеко всегда то, что тебе нужно, хотя и может угадать. :)
14 Ymryn
 
30.05.14
10:03
(12) а ты проверь, что в этом случае он покажет ;)
15 Ymryn
 
30.05.14
10:04
(13) *далеко не всегда то, что тебе нужно
16 Ymryn
 
30.05.14
10:05
(13) *изменятся. Блин, сколько ошибок, простите меня, пожалуйста.
17 Crush
 
30.05.14
10:05
Консоль запросов в руки.
Пока не Работает Цикл
Убираешь все группировки и условия.
Смотришь на таблицу.
Добавляешь условия (можно по одному).
Смотришь на таблицу, сортируешь, проверяешь.
Добавляешь группировки.
Смотришь на таблицу
КонецЦикла
18 Ymryn
 
30.05.14
10:06
(17) ты его так еще и рыбачить научишь. :)
19 Kurbash
 
30.05.14
10:11
(14)- я и проверил-даты разные
20 Ymryn
 
30.05.14
10:17
(19) Судя по полученному ответу, у меня складывается ощущение, что это неправильно. Я угадал? :)
В (17) тебе протянули удочку и даже дали краткую инструкцию. Рекомендую этим воспользоваться.
21 Kurbash
 
30.05.14
10:22
(20)ну да,неправильно...
22 Kurbash
 
30.05.14
10:22
(20)ну да, неправильно
23 Ymryn
 
30.05.14
10:28
(21), грустно. :( Не получился каменный цветок. Ну значит пока самый рабочий вариант - это (17).
24 Kurbash
 
30.05.14
10:34
не, кривой, после удаления таблица то слетает с номерами...признак какой нить булевый поставить, ставить галку...щас тумкать буду
25 Crush
 
30.05.14
10:40
(22) Расслабься, сядь в позу лотоса, соедини левым соединением средний палец правой руки с большим и большой палец левой руки со средним. Подумай о хорошем, о пятнице например. Произноси завывания типа "сдался мне в пятницу этот запрос?!"
Судя по (21) (22) ты торопишься. Хочешь с лёту понять искусство запросописания. Еще ни одному воину дракона такого не удавалось.
26 Kurbash
 
30.05.14
10:40
взлетает вроде, сейчас еще одну проверку поставлю и все
27 Kurbash
 
30.05.14
10:55
блин нормально получается:

запрос=новый запрос();
    запрос.Текст="ВЫБРАТЬ
                 |    а.номерстроки,
                 |    а.отм,
                 |    а.табном,
                 |    а.Фамилия,
                 |    а.Имя,
                 |    а.отчество,
                 |    а.датасобытия,
                 |    а.признаквхода
                 |ПОМЕСТИТЬ табл
                 |ИЗ
                 |    &состав КАК а
                 |;
                 |
                 |////////////////////////////////////////////////////////////////////////////////
                 |ВЫБРАТЬ
                 |    МИНИМУМ(т.номерстроки) КАК номстр,
                 |    МИНИМУМ(т1.номерстроки) КАК номстр1
                 |ИЗ
                 |    табл КАК т,
                 |    табл КАК т1
                 |ГДЕ
                 |    т.признаквхода = 1
                 |    И т1.признаквхода = 2
                 |    И т.табном = &табном
                 |    И т1.табном = &табном
                 |    И т1.отм = ЛОЖЬ
                 |    и т.отм = ЛОЖЬ";
             конеццикла;
запрос.УстановитьПараметр("Состав",состав.Выгрузить());
запрос.УстановитьПараметр("табном",стр.ТабНом);

результат=запрос.Выполнить().Выбрать();
пока результат.Следующий() цикл
если не значениезаполнено(результат.номстр) тогда    
    ДатаВхода="";
иначе
    ст=состав[результат.номстр-1];
ст.отм=Истина;
ДатаВхода=ст.ДатаСобытия;
конецесли;

если не значениезаполнено(результат.номстр1) тогда
    ДатаВыхода="";
    иначе
ст1=состав[результат.номстр1-1];
ст1.отм=Истина;
ДатаВыхода=ст1.ДатаСобытия;
конецесли;
сообщить(""+ДатаВхода+"|||"+ДатаВыхода);


только вот не канает если вход без выхода или наоборот....пустое знаечние всех дат выводит, надо что то думат с условием
28 dmpl
 
30.05.14
10:58
(24) Таблицу с номерами потом левым или правым соединением цепляй.
29 Kurbash
 
30.05.14
11:01
мне кажется 27 можно как нить доработать
30 Kurbash
 
30.05.14
11:23
ни у кого мыслей нет?
31 dmpl
 
30.05.14
11:26
(30) Есть - куда пропала дата события?
32 Аннушка
 
30.05.14
11:29
А тебе во второй таблице для каждого табельного номера нужен и вход и выход? или только то, что имеется? если есть вход, но нет выхода, должна быть одна строка или две?
33 Аннушка
 
30.05.14
11:37
Попробуй сделать объединение двух таблиц. В первой ставишь условие на признак входа 1, во второй на признак входа 2, в обоих таблицах оставляешь табельный номер, признак входа и дату, группируешь по таб. номеру и признаку входа, а дату берёшь максимумом - получаешь таблицу, в которой для каждого табельного номера есть признак входа и дата. Выгружаешь туда, куда тебе нужно.

Далее на счёт удаления. Соединяешь первоначальную таблицу с полученной таблицей левым соединением по табельному номеру, признаку входа и дате. Ставишь условие ГДЕ ВтораяТаблица.ТабНом ЕСТЬ NULL. Выгружаешь полученное в таблицу. Эта новая таблица и есть нужная. Проще, чем удалять из старой.
34 Aleksandr N
 
30.05.14
11:40
(27) Запрос в цикле... это ужасно(
35 Kurbash
 
30.05.14
12:05
(33) ни фига не понял))))мозги уже просто в кучу
36 Аннушка
 
30.05.14
13:33
первая таблица твоя из (0), далее так:

...
|ВЫБРАТЬ
|    табл.ТабНом,
|    1 КАК ПризнакВхода,
|    МАКСИМУМ(табл.ДатаСобытия) КАК ДатаСобытия
|ПОМЕСТИТЬ ПоследниеВходыВыходы
|ИЗ
|    табл КАК табл
|ГДЕ
|    табл.ПризнакВхода = 1
|
|СГРУППИРОВАТЬ ПО
|    табл.ТабНом
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
|    табл.ТабНом,
|    2,
|    МАКСИМУМ(табл.ДатаСобытия)
|ИЗ
|    табл КАК табл
|ГДЕ
|    табл.ПризнакВхода = 2
|
|СГРУППИРОВАТЬ ПО
|    табл.ТабНом
|;
|
|ВЫБРАТЬ
|    табл.ТабНом,
|    табл.Фамилия,
|    табл.Имя,
|    табл.Отчество,
|    табл.ДатаСобытия,
|    табл.ПризнакВхода
|ИЗ
|    табл КАК табл
|        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПоследниеВходыВыходы КАК ПоследниеВходыВыходы
|        ПО табл.ТабНом = ПоследниеВходыВыходы.ТабНом
|            И табл.ДатаСобытия = ПоследниеВходыВыходы.ДатаСобытия
|            И табл.ПризнакВхода = ПоследниеВходыВыходы.ПризнакВхода
|;
|
|ВЫБРАТЬ
|    табл.ТабНом,
|    табл.Фамилия,
|    табл.Имя,
|    табл.Отчество,
|    табл.ДатаСобытия,
|    табл.ПризнакВхода
|ИЗ
|    табл КАК табл
|        ЛЕВОЕ СОЕДИНЕНИЕ ПоследниеВходыВыходы КАК ПоследниеВходыВыходы
|        ПО табл.ТабНом = ПоследниеВходыВыходы.ТабНом
|            И табл.ДатаСобытия = ПоследниеВходыВыходы.ДатаСобытия
|            И табл.ПризнакВхода = ПоследниеВходыВыходы.ПризнакВхода
|ГДЕ
|    ПоследниеВходыВыходы.ТабНом ЕСТЬ NULL";

МассивРезультатов = Запрос.ВыполнитьПакет();
Результат1 = МассивРезультатов[2];
Результат2 = МассивРезультатов[3];

ТаблицаСМаксимумами = Результат1.Выгрузить();
ТаблицаСУдалённымиМаксимумами = Результат2.Выргузить();


как-то так, потестируй
37 Аннушка
 
30.05.14
13:34
в последней строке "Выгрузить", а то перепутала буквы местами
38 Аннушка
 
30.05.14
14:14
А вообще зря я объединение делала. В моём коде первый запрос можно сделать такой:

|ВЫБРАТЬ
|    табл.ТабНом,
|    табл.ПризнакВхода,
|    МАКСИМУМ(табл.ДатаСобытия) КАК ДатаСобытия
|ПОМЕСТИТЬ ПоследниеВходыВыходы
|ИЗ
|    табл КАК табл
|
|СГРУППИРОВАТЬ ПО
|    табл.ТабНом,
|    табл.ПризнакВхода

а два других такие же
Независимо от того, куда вы едете — это в гору и против ветра!