Всем привет. 1С .7.7 Торговля. Есть Справочник Контрагенты и есть подчиненный ему справочник КатегорииКонтрагентов с реквизитом "категория" (тип: СправочникКатегории). Выбрать запросом Контрагентов, которые являются Владельцами этих категорий я могу. Реально ли Запросом отобрать Контрагентов которые не являются Владельцами?Т.е. у которых вообще нет катгорий? Я в 8-ке это сделал за 5 минут.В 7-ке над этой задачей сижу уже 3 день.
Группа: Пользователи
Сообщений: 96
Спасибо сказали: 8 раз
Рейтинг: 0
Цитата(Flexy @ 30.01.12, 17:20)
Всем привет. 1С .7.7 Торговля. Есть Справочник Контрагенты и есть подчиненный ему справочник КатегорииКонтрагентов с реквизитом "категория" (тип: СправочникКатегории). Выбрать запросом Контрагентов, которые являются Владельцами этих категорий я могу. Реально ли Запросом отобрать Контрагентов которые не являются Владельцами?Т.е. у которых вообще нет катгорий? Я в 8-ке это сделал за 5 минут.В 7-ке над этой задачей сижу уже 3 день.
Заранее Спасибо.
Вопрос - зачем запросом? Можно и выборкой (иногда в разы быстрее получается). думаю и просто запросом можно. надо пробовать но я бы копал в сторону типа такого
Вопрос - зачем запросом? Можно и выборкой (иногда в разы быстрее получается). думаю и просто запросом можно. надо пробовать но я бы копал в сторону типа такого
Выборкой я пробовал.Ооооочень долго перебирает. Да и у меня уже чисто спортивный интерес сделать это именно запросом.
А попробовать в запросе выбрать Контрагент=Справочник.Контрагенты.ТекущийЭлемент и поставить условие только те у которых пустоезначение(КатегорииКонтрагентов).. может так,,?
Группа: Пользователи*
Сообщений: 940
Спасибо сказали: 285 раз
Рейтинг: 0
Если сходу, то можно так:
//******************************************* Функция КвоКатегорий(ТекКонтрагент) Перем Запрос, ТекстЗапроса, Таб; //Создание объекта типа Запрос Запрос = СоздатьОбъект("Запрос"); ТекстЗапроса = "//{{ЗАПРОС(ПроверкаКатегорий) |КатегорииКонтрагентов = Справочник.КатегорииКонтрагентов.ТекущийЭлемент; |Владелец = Справочник.КатегорииКонтрагентов.Владелец; |Группировка КатегорииКонтрагентов; |Условие(Владелец = ТекКонтрагент); |"//}}ЗАПРОС ; // Если ошибка в запросе, то выход из процедуры Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда Возврат -1; КонецЕсли;
Если Запрос.Группировка(1) = 0 Тогда Возврат 0; КонецЕсли; Возврат 1; КонецФункции
//******************************************* Процедура Сформировать() Перем Запрос, ТекстЗапроса, Таб; Запрос = СоздатьОбъект("Запрос"); ТекстЗапроса = "//{{ЗАПРОС(Сформировать) |Контрагент = Справочник.Контрагенты.ТекущийЭлемент; |Группировка Контрагент Без групп; |"//}}ЗАПРОС ; // Если ошибка в запросе, то выход из процедуры Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда Возврат; КонецЕсли;
Таб = СоздатьОбъект("Таблица"); Пока Запрос.Группировка(1) = 1 Цикл Если КвоКатегорий(Запрос.Контрагент)=0 Тогда Таб.ВывестиСекцию("Контрагенты"); КонецЕсли; // КвоКатегорий(Запрос.Контрагент)=0 КонецЦикла; Таб.ТолькоПросмотр(1); Таб.Показать("Сформировать", ""); КонецПроцедуры
Спасибо. Обязательно попробую этот способ.Но Имхаеться мне, что он не оптимален. Но все равно мне очень интересно, реально ли получить нужные мне данные с помощью одного только запроса, Без написания доп. функций и тупого перебора. Либо в 7-ке язык запросов не позволяет выполнить столь не сложную задачу?
Группа: Пользователи
Сообщений: 96
Спасибо сказали: 8 раз
Рейтинг: 0
Цитата(Flexy @ 30.01.12, 18:42)
Спасибо. Обязательно попробую этот способ.Но Имхаеться мне, что он не оптимален. Но все равно мне очень интересно, реально ли получить нужные мне данные с помощью одного только запроса, Без написания доп. функций и тупого перебора. Либо в 7-ке язык запросов не позволяет выполнить столь не сложную задачу?
Тогда прямые запросы вам в руки. Очень быстро летает
Кстати вот что подумалось
1. первым запросом получаем список всех контрагентов у которых есть категории 2. вторым запросом получаем всех остальных (не вошедших в первый запрос)
Цитата(5_kopeek @ 30.01.12, 18:33)
Если сходу, то можно так:
//******************************************* Функция КвоКатегорий(ТекКонтрагент) Перем Запрос, ТекстЗапроса, Таб; //Создание объекта типа Запрос Запрос = СоздатьОбъект("Запрос"); ТекстЗапроса = "//{{ЗАПРОС(ПроверкаКатегорий) |КатегорииКонтрагентов = Справочник.КатегорииКонтрагентов.ТекущийЭлемент; |Владелец = Справочник.КатегорииКонтрагентов.Владелец; |Группировка КатегорииКонтрагентов; |Условие(Владелец = ТекКонтрагент); |"//}}ЗАПРОС ; // Если ошибка в запросе, то выход из процедуры Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда Возврат -1; КонецЕсли;
Если Запрос.Группировка(1) = 0 Тогда Возврат 0; КонецЕсли; Возврат 1; КонецФункции
//******************************************* Процедура Сформировать() Перем Запрос, ТекстЗапроса, Таб; Запрос = СоздатьОбъект("Запрос"); ТекстЗапроса = "//{{ЗАПРОС(Сформировать) |Контрагент = Справочник.Контрагенты.ТекущийЭлемент; |Группировка Контрагент Без групп; |"//}}ЗАПРОС ; // Если ошибка в запросе, то выход из процедуры Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда Возврат; КонецЕсли;
Таб = СоздатьОбъект("Таблица"); Пока Запрос.Группировка(1) = 1 Цикл Если КвоКатегорий(Запрос.Контрагент)=0 Тогда Таб.ВывестиСекцию("Контрагенты"); КонецЕсли; // КвоКатегорий(Запрос.Контрагент)=0 КонецЦикла; Таб.ТолькоПросмотр(1); Таб.Показать("Сформировать", ""); КонецПроцедуры
Но будет ли быстрее?..
Запрос в цикле? За это убивать надо
Кстати, на заметку ВСЕМ (и автору темы в свете моего предложения из предыдущего поста)
Если у вас есть список значений (именно список элементов а не группа справочника) по которому надо поставить условие в запросе то конструкция
предлагаю свой вариант, потратила конечно не 5мин, а где-то 10-15 проверен на аналогичном справочнике и подчиненном ему - работает первый запрос - выдает тех Контрагентов, у которых есть подчиненные КатегорииКонтрагентов, но реквизит Категории пустой, а второй - тех Контрагентов, у которых НЕТ подчиненных КатегорииКонтрагентов
Перем СпрПодч;
//******************************************* Функция НаличиеПодчСпр(Владелец) СпрПодч.ИспользоватьВладельца(Владелец); Возврат СпрПодч.ВыбратьЭлементы(); КонецФункции //НаличиеПодчСпр
//******************************************* Процедура Сформировать() Запрос = СоздатьОбъект("Запрос"); ТекстЗапроса = "//{{ЗАПРОС(Сформировать) |Владелец = Справочник.КатегорииКонтрагентов.Владелец; |Категории = Справочник.КатегорииКонтрагентов.Категории; |Группировка Владелец без групп; |Условие(ПустоеЗначение(Категории)=1); |"//}}ЗАПРОС ; Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда Возврат; КонецЕсли;
Таб = СоздатьОбъект("Таблица"); Пока Запрос.Группировка(1) = 1 Цикл пВладелец = Запрос.Владелец; Таб.ВывестиСекцию("Строка"); КонецЦикла; Таб.ТолькоПросмотр(1); Таб.Показать("Сформировать", "");
Запрос2 = СоздатьОбъект("Запрос"); ТекстЗапроса2 = "//{{ЗАПРОС(Сформировать2) |Владелец = Справочник.Контрагенты.ТекущийЭлемент; |Группировка Владелец без групп; |Условие(НаличиеПодчСпр(Владелец)=0); |"//}}ЗАПРОС ; Если Запрос2.Выполнить(ТекстЗапроса2) = 0 Тогда Возврат; КонецЕсли;
Таб = СоздатьОбъект("Таблица"); Пока Запрос2.Группировка(1) = 1 Цикл пВладелец = Запрос2.Владелец; Таб.ВывестиСекцию("Строка"); КонецЦикла; Таб.ТолькоПросмотр(1); Таб.Показать("Сформировать", "");
КонецПроцедуры
1С Предприятие 7.7: Бух. учет для Украины (активно дописанная) + самописка (учет производства и ЗП) 1С Предприятие 8.3: Бух.предприятия 3.0 + самописка ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Кроме высшего образования, нужно иметь хотя бы среднее соображение
Кстати, на заметку ВСЕМ (и автору темы в свете моего предложения из предыдущего поста) Если у вас есть список значений (именно список элементов а не группа справочника) по которому надо поставить условие в запросе то конструкция Условие (СписокУсловий.Принадлежит(РеквизитЗапроса)<>0); работает на порядок быстрее чем стандартная Условие (РеквизитЗапроса в СписокУсловий);
У меня также замечание: осторожнее с выражением "на порядок". На порядок выше - это в 10 раз! Так ли это на самом деле в данном случае? Вот интересная статься на эту тему: [необходимо зарегистрироваться для просмотра ссылки] Или на форуме: [необходимо зарегистрироваться для просмотра ссылки]
Группа: Пользователи
Сообщений: 96
Спасибо сказали: 8 раз
Рейтинг: 0
Цитата(vadim007 @ 31.01.12, 9:30)
У меня также замечание: осторожнее с выражением "на порядок". На порядок выше - это в 10 раз! Так ли это на самом деле в данном случае? Вот интересная статься на эту тему: [необходимо зарегистрироваться для просмотра ссылки] Или на форуме: [необходимо зарегистрироваться для просмотра ссылки]
Советую проверить. ЧТо такое "на порядок" я в курсе
Цитата(nysysimara @ 31.01.12, 9:07)
предлагаю свой вариант, потратила конечно не 5мин, а где-то 10-15 проверен на аналогичном справочнике и подчиненном ему - работает первый запрос - выдает тех Контрагентов, у которых есть подчиненные КатегорииКонтрагентов, но реквизит Категории пустой, а второй - тех Контрагентов, у которых НЕТ подчиненных КатегорииКонтрагентов
Перем СпрПодч;
//******************************************* Функция НаличиеПодчСпр(Владелец) СпрПодч.ИспользоватьВладельца(Владелец); Возврат СпрПодч.ВыбратьЭлементы(); КонецФункции //НаличиеПодчСпр
//******************************************* Процедура Сформировать() Запрос = СоздатьОбъект("Запрос"); ТекстЗапроса = "//{{ЗАПРОС(Сформировать) |Владелец = Справочник.КатегорииКонтрагентов.Владелец; |Категории = Справочник.КатегорииКонтрагентов.Категории; |Группировка Владелец без групп; |Условие(ПустоеЗначение(Категории)=1); |"//}}ЗАПРОС ; Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда Возврат; КонецЕсли;
Таб = СоздатьОбъект("Таблица"); Пока Запрос.Группировка(1) = 1 Цикл пВладелец = Запрос.Владелец; Таб.ВывестиСекцию("Строка"); КонецЦикла; Таб.ТолькоПросмотр(1); Таб.Показать("Сформировать", "");
специально проверила: в справочнике (который владелец) 3100 позиций в ДБФе отрабатывает за 3 секунды
ЗЫ: замер делала с помощью
МиллиCек0 = _GetPerformanceCounter(); //в начале процедуры сформировать Сообщить("выполнено за "+окр((_GetPerformanceCounter()-МиллиCек0)*0.001)+"сек"); //в конце процедуры
1С Предприятие 7.7: Бух. учет для Украины (активно дописанная) + самописка (учет производства и ЗП) 1С Предприятие 8.3: Бух.предприятия 3.0 + самописка ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Кроме высшего образования, нужно иметь хотя бы среднее соображение
Группа: Пользователи
Сообщений: 96
Спасибо сказали: 8 раз
Рейтинг: 0
Цитата(nysysimara @ 31.01.12, 10:32)
специально проверила: в справочнике (который владелец) 3100 позиций в ДБФе отрабатывает за 3 секунды
ЗЫ: замер делала с помощью
МиллиCек0 = _GetPerformanceCounter(); //в начале процедуры сформировать Сообщить("выполнено за "+окр((_GetPerformanceCounter()-МиллиCек0)*0.001)+"сек"); //в конце процедуры
На таком количестве и такая функция - возможно. Но если у вас будет 10000-15000 элементов-владельцев и функция чуть посложнее? Кроме того я сказал обобщённо а не в применении к текущему запросу или теме
Процедура Сформировать() МиллиCек0 = _GetPerformanceCounter(); //в начале процедуры сформировать
Сообщить("выполнено за "+окр((_GetPerformanceCounter()-МиллиCек0)*0.001)+"сек"); //в конце процедуры
КонецПроцедуры
время выполнения 3 сек.Количество элементов в справочнике "Контрагенты" - 5500.
Процедура Сформировать() МиллиCек0 = _GetPerformanceCounter(); //в начале процедуры сформировать
СпрКонтрагенты=СоздатьОбъект("Справочник.Контрагенты"); СпрАгенты=СоздатьОбъект("Справочник.АгентыКлиента"); СписокКонтрагентов=СоздатьОбъект("СписокЗначений"); СпрКонтрагенты.ВыбратьЭлементы(); Пока СпрКонтрагенты.ПолучитьЭлемент()=1 Цикл Если (СпрКонтрагенты.ЭтоГруппа()=1) или (СпрКонтрагенты.ПометкаУдаления()=1) Тогда Продолжить; КонецЕсли; СпрАгенты.ИспользоватьВладельца(СпрКонтрагенты.ТекущийЭлемент()); Если СпрАгенты.ВыбратьЭлементы(1)=0 Тогда СписокКонтрагентов.ДобавитьЗначение(СпрКонтрагенты.ТекущийЭлемент()); КонецЕсли; КонецЦикла;
Сообщить("выполнено за "+окр((_GetPerformanceCounter()-МиллиCек0)*0.001)+"сек"); //в конце процедуры
КонецПроцедуры
время выполнения 3 сек.Количество элементов в справочнике "Контрагенты" - 5500.
предлагаю свой вариант, потратила конечно не 5мин, а где-то 10-15
Спасибо.На моей базе Ваш вариант работает быстрее, чем просто выборка.
Все равно хочу сделать этот только запросом.Без использования функций и т.д., Т.к. база довольно большая, и есть шанс, что все же выбирать будет еще быстрее. Но городить прямые запросы ради одной обработки, как-то облом...
Группа: Пользователи
Сообщений: 62
Спасибо сказали: 14 раз
Рейтинг: 0
тогда так, только долго.
Запрос = СоздатьОбъект("Запрос"); ТекстЗапроса = "//{{ЗАПРОС(Сформировать) |Влад = Справочник.Контрагенты.ТекущийЭлемент, Справочник.КатегорииКонтрагентов .Владелец; |категория= Справочник.КатегорииКонтрагентов .категория; |Функция СК = Счётчик(); |Группировка Влад без групп; |Группировка категория без групп; |"//}}ЗАПРОС ; // Если ошибка в запросе, то выход из процедуры Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда Возврат; КонецЕсли;
// Подготовка к заполнению выходных форм данными запроса Таб = СоздатьОбъект("Таблица"); Таб.ИсходнаяТаблица("Сформировать"); // Заполнение полей "Заголовок" Таб.ВывестиСекцию("Заголовок"); Состояние("Заполнение выходной таблицы..."); Таб.Опции(0, 0, Таб.ВысотаТаблицы(), 0); Пока Запрос.Группировка(1) = 1 Цикл // Заполнение полей Влад Если Запрос.СК = 1 Тогда Таб.ВывестиСекцию("Влад"); КонецЕсли; КонецЦикла;
Группа: Пользователи
Сообщений: 96
Спасибо сказали: 8 раз
Рейтинг: 0
Цитата(g789 @ 31.01.12, 13:25)
тогда так, только долго.
Запрос = СоздатьОбъект("Запрос"); ТекстЗапроса = "//{{ЗАПРОС(Сформировать) |Влад = Справочник.Контрагенты.ТекущийЭлемент, Справочник.КатегорииКонтрагентов .Владелец; |категория= Справочник.КатегорииКонтрагентов .категория; |Функция СК = Счётчик(); |Группировка Влад без групп; |Группировка категория без групп; |"//}}ЗАПРОС ; // Если ошибка в запросе, то выход из процедуры Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда Возврат; КонецЕсли;
// Подготовка к заполнению выходных форм данными запроса Таб = СоздатьОбъект("Таблица"); Таб.ИсходнаяТаблица("Сформировать"); // Заполнение полей "Заголовок" Таб.ВывестиСекцию("Заголовок"); Состояние("Заполнение выходной таблицы..."); Таб.Опции(0, 0, Таб.ВысотаТаблицы(), 0); Пока Запрос.Группировка(1) = 1 Цикл // Заполнение полей Влад Если Запрос.СК = 1 Тогда Таб.ВывестиСекцию("Влад"); КонецЕсли; КонецЦикла;
Простите, Вы пробуете на реальной базе то что пишете или так - "с листа" копируете на форум?
Flexy, найдете оптимальное решение - похвастайтесь. (тоже стало интересно)
1С Предприятие 7.7: Бух. учет для Украины (активно дописанная) + самописка (учет производства и ЗП) 1С Предприятие 8.3: Бух.предприятия 3.0 + самописка ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Кроме высшего образования, нужно иметь хотя бы среднее соображение
1С Предприятие 8.3, 1С Предприятие 8.2, 1С Предприятие 8.1, 1С Предприятие 8.0, 1С Предприятие 7.7, Литература 1С, Общие вопросы по администрированию 1С, Методическая поддержка 1С - всё в одном месте: на Украинском 1С форуме!