Приветствую.
У меня поле LookupDataControl отображает список одного из полей датасета(Description).
Допустим, я выбрал из списка одно из значений.
Как мне получить соответствующия этому Description значения из других колонок(например его ID и т.д.)?
Нравится
То есть, как мне можно обратиться, каким методом к полю LookupDataControl, забрать из него значения соответствующие соседней другим колонкам в записи?
Что я только не перепробовал...
edt...LookupDataset.DataFields('ID').Value...
Миллион этих вариаций. Не могу никак угадать и попасть в метод. Выручайте...)
Как вообще зацепиться за лукап датасет какого-то поля и обращаться к его колоночкам?
В функции OnPrepareSelectWindow всё просто, там этот лукапДС передается в виде параметра, а самому как его взять...Туплю)
Поле справочного типа (Lookup) содержит идентификатор (ID) и отображаемое значение.
Код вида:
var OfferingID = dlData.Dataset.Values('OfferingID');
вернет идентификатор выбранного значения.
Такой код:
var OfferingName = dlData.Dataset.DisplayValues('OfferingID');
вернет отображаемое значение.
Где OfferingID - название поля в датасете.
Чтобы получить по идентификатору выбранного значения информацию других полей датасета справочника (например, код выбранного продукта), необходимо использовать фильтрацию:
var OffDataset = Services.GetNewItemByUSI('ds_Offering'); ApplyDatasetFilter(OffDataset, 'OfferingID', OfferingID, true); OffDataset.Open(); var OfferingCode = OffDataset.Values('Code'); OffDataset.Close();
Наталья, у меня чуть замороченее ситуация:
Упрощу для рассказа:
Есть поле ввода Индекса(IntegerDataControl) скажем для датасета dlData.
Второе поле - LookupDataControl для датасета dlContact.
После ввода числа в поле Индекса на событии выхода из поля OnExit происходит присваивание переменной Index, равной соответственно введенному значению.
На событии OnPrepareSelectWindow для LookupDataControl'a поля у меня происходит ApplyDatasetFilter(LookupDataset, 'Index', Index, true), после чего лукапдатасет рефрешется, и в выпадающем списке остаются уже отфильтрованные по индексу строчки.
Мне требуется:
1. Выбрать одну любую строчку
2. Получить значение этой строчки(которое отображается) (Description)
3. Получить соответствующую этому Description запись из другого столбца, к примеру(ID), либо (City) и т.д.
Я не могу понять каким методом обратиться к этому полю чтобы достать значения из соседних столбцов записи, т.к. параметр LookupDataControl как я видел передается в функции OnPrepareSelectWindow . Там я через нее могу обратиться к нужному столбцу, но мне нужно понять как обращаться к отфильтрованному лукапдатасету из других функций, к текущему значению понятно как, а как обратиться к другим полям, которые есть в этом справочнике и также доступны для отображения.
Что-то как-то запутано объясняете.
У вас это все происходит в карточке редактирования?
Наталья объяснила основы, я попробую показать на примере, может яснее станет либо для вас, либо для нас, что же вы хотите.
Допустим надо узнать первое средство связи основного контакта из карточки контрагента, тогда нам надо
посмотреть, что из себя представляет lookup-поле "основной контакт"
DatasetLink = dlData
DataFieldName = PrimaryContactID
тогда
//узнаем id основного контакта var ContactID = dlData.Dataset.Values('PrimaryContactID'); //проверка на то, что в поле указан основной контакт if (ContactID !=null) { //берем запись контакта из датасета, к которому он привязан, это можно узнать в ds_Account var ContactDataset = GetOpenedDatasetByUSIWithFilter('ds_Contact','ID', ContactID); //записываем в переменные значения интересующих нас полей var Communication1 = ContactDataset.Values('Communication1'); var Communication1TypeName = GetDatasetFieldValueByID('ds_CommunicationType', ContactDataset('Communication1TypeID'), 'Name') //зная id записи с помощью этой функции можно вынуть значения нужного нам поля //в итоге можно вывести, например "Телефон: 123456" или "e-mail: 123123.ru" Log.Write(1, Communication1TypeName + ': ' + Communication1); }
Вот так можно получать нужную вам информацию.
Наталья, строчка dlData.Datset.Values('Value') возвращает то что нужно, но проблема в том, что когда я меняю значение в поле LookupDataControl - значение остается прежним(для поля, которое выбирается по умолчанию), а не переписывается на новое выбранное. Как возможно это решить?
Проще говоря, я думал что при смене значения в лукапдатаконтроле, позиционирование датасета на запись соответственно этому контролу меняется. А тут походу нет...Помогите разобраться..
Когда меняете значение поля скриптом, поле у вас выделено (находится в активном состоянии)?
"Сазанов Александр Владимирович" написал:Когда меняете значение поля скриптом, поле у вас выделено (находится в активном состоянии)?
Оно активируется в случае наличия записей в датасете после фильтрации. Если есть записи ->dlDataset.Open();
Видимо не так меня поняли, или я не так вас понял, может быть у вас похожая проблема как эта?
В общем конкретизирую и объясню задачу:
Имеется поле для ввода данных(Index) в ручную.
Имеется поле LookupDataControl(привязан к датасету dlData).
При вводе данных вполе Index после выхода из него на событии OnExit происходит присваивание переменной Index в соответствии с введенным значением, сразу же активируется фильтр ApplyDatasetFilter(dlData.Dataset, 'Index', Index, true).
После чего, выполяется условие
if (dlData.Dataset.RecordsCount > 0){
dlData.Dataset.Open();
}
Отсюда поле становится активным.
На событии OnPrepareSelectWindow у данного LookupDataControl выполняется функция:
PrepareLookupDataControl(LookupDataControl, dlDemand.Dataset);
var Dataset = dlDemand.Dataset;
var DataFieldName = LookupDataControl.DataFieldName;
var DataField = Dataset.DataFields.ItemsByName(DataFieldName);
var Index = dlNewContactClient.Dataset.DataFields('Index').Value;
var LookupDataset = DataField.LookupDataset;
ApplyDatasetFilter(LookupDataset , 'Index', Index, true);
edtDemandAdress.UnprepareDropdownList();
RefreshDataset(LookupDataset );
В конечном итоге, у меня остается нескольо записей в лукап датаконтроле, я не могу понять как при смене записи там, сделать так чтобы менялось позиционирование записи в основном датасете.
В общем я жутко запутался)))
Блин, вот даже если скажем заменяем поле на обычный LookupControl, там нажимаем на лупу, открывается справочник, в нем есть записи и все столбцы, выбираем запись, отображается скажем описание, как получить соответствующее этому описанию значение из другой колонки, как обратиться...
Да-с, запутливый у вас код, для начала
"Нестеров Артем Валерьевич" написал:ApplyDatasetFilter(dlData.Dataset, 'Index', Index, true).
После чего, выполяется условие
if (dlData.Dataset.RecordsCount > 0){
dlData.Dataset.Open();
}
Если у вас записей больше 0, то датасет dlData.Dataset уже открыт, то зачем его открывать второй раз или это уже надо открыть с фильтром? Либо переоткрыть, либо это вообще не надо.
if (dlData.Dataset.RecordsCount > 0) { ApplyDatasetFilter(dlData.Dataset, 'Index', Index, true); RefereshDataset(dlData.Dataset); }
Следующее, кто мешает получить LookupDataset в одну строчку?
var LookupDataset = LookupDataControl.DataField.LookupDataset;
Идем дальше, вы случаем не edtDemandAdressOnPrepareSelectWindow описали?
Только этим я могу объяснить строчки:
edtDemandAdress.UnprepareDropdownList();//тут вы сбрасываете список? RefreshDataset(LookupDataset );//а тут вы его переоткрываете?
Если это так, то edtDemandAdress.UnprepareDropdownList(); надо вешать туда, где вы считаете индекс, а тут он не нужен. Если не так, то я ничего не понял.
Следующее, что меня смущяет: dlData, dlDemand, dlNewContactClient. Такое количество датасетов обычно только в воркспейсе, но писать это там самоубийство, в скрипте какого окна все пишется грид или эдит?
Короче, на словах ничего не понятно, не видно. Надо подключаться, через teamviewer например.
Как обращаться я писал в комментарии 5 и Наталья в комментарии 3:
LookupControl.Value - будет содержать id записи
Допустим у вас к lookupControl привязаны контакты, выбираете, отображается "Иванов Иван", но их может быть 2-3, а то и более штук, поэтому в LookupControl храниться id контакта
получить датасет этого контакта можно так
var ContactDataset = GetOpenedDatasetByUSIWithFilter('ds_Contact', //USI датасета, к которому должен быть привязан lookup-поле 'ID', //название фильтра, он должен быть в sq_Contact LookupControl.Value //Id записи, которое мы получили );
потом получайте, что хотите
ContactDataset('Name')
ContactDataset('Address') и т.д.
"Нестеров Артем Валерьевич" написал:Блин, вот даже если скажем заменяем поле на обычный LookupControl, там нажимаем на лупу, открывается справочник, в нем есть записи и все столбцы, выбираем запись, отображается скажем описание, как получить соответствующее этому описанию значение из другой колонки, как обратиться...
В случае LookupControl получить значения можно так:
var Dataset = LookupControl.LookupDatasetLink.Dataset; Dataset.Locate('ID', LookupControl.Value); var FieldValue = GetFieldValueFromDisabledField(Dataset, 'FieldName')
Наталья, а LookupControl это имя поля получается?
Дальше появилась вообще непонятная проблема.
Ввожу индекс, выхожу из поля, на событии OnExit происходит фильтрация датасета и его рефреш, в поле LookupControl выбираю одно из отфильтрованных значений(всё работает как надо).
Если после этого я снова ввожу индекс, то появляется неопознанная ошибка. Пробовал уже и закрывать датасет - ничего не помогает. Проще говоря, если что-то выбрано в поле LookupControl, то при изменении индекса появляется ошибка(на моменте выполнения рефреша). Также пробовал присвоить LookupControl.Value = null - проблема также остается. Прошу помощи.
P.S. Как я понял, может помочь деинициализация этого LookupControl'a, но не знаю как этого сделать и возможно ли это...
Наталья, может ЛукапКонтрол прописывается куда-то в атрибуты окна? Как вернуть его состояние до захода?
Наталья, так сможете посмотреть?
function edtIndexOnExit(Control) { //Ловим значение на OnExit из вводимого поля индекса var Index = dlNewContactClient.Dataset.DataFields('Index').Value; //Само значение var DemandDataset = dlDemand.Dataset; //Датасет по которому производится фильтрация для просмотра лукап поля edtDemand.Value = null; //Обнуляю значение лукап поля для случая изменения индекса if (Index != null){ var IsDemand = CheckIsDemandPossible(DemandDataset, Index); //Ну собственно, начали } } function CheckIsDemandPossible(DemandDataset, Index){ DemandDataset.Close(); //Закрыл датасет для фильтрации(на случай если уже открывали при обращении к лукапу) ApplyDatasetFilter(DemandDataset, 'Index', Index, true); //Включили фильтр DemandDataset.Open(); //---Здесь и идет сваливание,если поле лукапа было открыто пользователем--- if (DemandDataset.RecordsCount != 0){ //Это уже возвращаемые значения для дальнейшей работы if (System.MessageDialog("Индекс запрещен к отправке.\r\nОформить до востребования - нажмите 'да', \r\nотменить заказ - нажмите 'нет'", mdtWarning, (mdbYes + mdbNo), 0) == wmrYes) { return 1; } else return 0; } return 2; } /*Не понятно почему он не хочет открываться в нужном месте. Если придется убирать оттуда это открытие – это потянет за собой переработку логики модуля. Может быть есть способ деинициализировать лукапконтрол, т.е. перевести его в то состояние, каким он является до начала работы с ним? Всё комьюнити перерыл – ничего не нашел.*/
Когда в лукапконтрол не заходишь - всё отрабатывает великолепно. Но стоит туда зайти, даже не обязательно выбирая запись просто выйти - при следующем OnExit датасет уже не открывается в том месте где я указал сваливание
Артем попробуйте переделать функцию так (если фильтр применяется для чего-то еще, то не подойдет, если только узнать кол-во, то можно работать с копией):
function CheckIsDemandPossible(DemandDataset, Index) { var DemandDatasetCopy = Services.GetNewItemByUSI(DemandDataset.USI); DemandDatasetCopy.Close(); //Закрыл датасет для фильтрации(на случай если уже открывали при обращении к лукапу) ApplyDatasetFilter(DemandDatasetCopy, 'Index', Index, true); //Включили фильтр DemandDatasetCopy.Open(); //все еще есть сваливание? if (DemandDatasetCopy.RecordsCount != 0) { //Это уже возвращаемые значения для дальнейшей работы if (System.MessageDialog("Индекс запрещен к отправке.\r\nОформить до востребования - нажмите 'да', \r\nотменить заказ - нажмите 'нет'", mdtWarning, (mdbYes + mdbNo), 0) == wmrYes) { return 1; } else return 0; } return 2; }
Артем, отладчик ставили перед Dataset.Open?
Можно увидеть текст запроса (Dataset.SelectQuery.SQLText) который будет отправлен на сервер?
Также советую перед Dataset.Open() делать EnableDatasetFilters(Dataset, false);
PS: а какая ошибка при свале на Dataset.Open() ?
Артем, честно говоря немного запуталась в возникающих у Вас ошибках.
Давайте поступим так: вложите сервисы, которые позволят мне протестировать работу логики. Я проведу работы и точно смогу сказать в чем причина ошибок, как их устранять.