Реализация матричной формы с помощью веб-служб
Постоянные читатели наверняка заметили, что написав РѕРґРЅСѓ статью РїРѕ некой теме СЏ редко РјРѕРіСѓ сдержать графоманские позывы. Рто часто ведет Рє появлению целого цикла статей посвященного РѕРґРЅРѕР№ тематике. Так было СЃ отчетами , СЃ подключаемыми компонентами , теперь настал черед веб-служб, знакомство СЃ которыми РјС‹ начали РІ предыдущем выпуске .
Прошлый раз мы остановились на создании приложения, которое демонстрировало возможности по работе с веб-служами, а также отображало остатки по товарам. Последним аккордом было создание столбца отображающего информацию о наличии товаров на Синем складе .
Уже догадались к чему я клоню?
Да, да. Я тоже подумал о создании матричной формы.
Как известно РІ версии NAV 2009 СЃ матричными формами есть проблемы. Даже так. Р?значально РІ Dynamics NAV 2009 матричные формы перестали поддерживаться Рё были заменены недружелюбными поделками РЅР° базе страниц (Page). Хотя СЏ Рё РЅРµ являюсь фанатом матричных форм, однако волею СЃСѓРґСЊР±С‹ внес некий вклад РІ смягчение сложившейся ситуации:
- Статья, разъясняющая как реализованы матричные формы в Dynamics NAV 2009.
- Статья, описывающая альтернативный подход к реализации матричных форм. Будучи в Сиэтле показывал пример реализации Freddy, позже такой подход стал использоваться в SP1. Вполне возможно, что это совпадение, т.к. Freddy специализируется в другой области.
- Реализация матричных форм СЃ помощью отчетов. Отправил Claus’Сѓ прототип отчета Рё описание ошибки, затрудняющей использование элемента управления Matrix. После выхода SP1, РІ котором данная ошибка была исправлена, Claus активно рассказывал Рѕ данной возможности как РЅР° своем блоге, так Рё РЅР° мероприятиях Microsoft (РЅР° слайдах посвященных NAV 2009 SP1 РјРѕР¶РЅРѕ заметить зеленый матричный отчет).
Но никогда не следует останавливаться на достигнутом и сейчас мы попробуем реализовать матричную форму с помощью веб-служб.
Для начала создадим простое приложение считывающее записи РёР· таблицы 27 Item. Ртом посвящена статья из предыдущего выпуска , рекомендую СЃ ней ознакомиться перед тем как приступать Рє чтению настоящей статьи.
Вот что должно получиться.
Рто было работающее приложение. Рђ РІРѕС‚ весь написанный для этого приложения РєРѕРґ:
Не забываем, что нужно добавить Web Reference, DataGridView и BindingSource. Помним, что веб-служба должна быть опубликована, а служба Microsoft Dynamics NAV Business Web Services – запущена.
Ну что ж. Подготовительный этап завершен. Перейдем к созданию добавленной стоимости.
Так как мы хотим создать матричную форму, то и действовать надо соответственно. Для начала вспомним о том, что классические матричные формы используют две связанные таблицы – одна для строк, другая для столбцов. Значит нам нужно поступить также.
Для этого опубликуем еще одну веб-службу. В дополнение к товарам, мы опубликуем еще и перечень складов – это страница 15. Назовем службу LocationList:
Далее добавим ссылку на эту веб-службу в наше приложение.
Обратите внимание, что в отличие от веб-службы на базе карточки товара, список складов имеет меньше доступных методов. Данная веб-служба не предоставляет возможности ни создать, ни удалить, ни изменить склад. Только чтение.
Причина кроется в свойствах самой страницы, на базе которой создана веб-служба.
Как видно на рисунке, для данной страницы в свойстве Editable установлено значение No, что делает страницу нередактируемой. Такое же поведение сохраняется и после публикации страницы в качестве веб-службы.
Но пора бы немного пописать код, понятно что делать это мы будем в Visual Studio, а код будет на языке C#.
Добавим в начало функции Form1_Load вызов метода CreateLocationColumns(), а ниже добавим и сам метод.
private void CreateLocationColumns(){ В LocationListWS.LocationList_Service LocationListService В = new LocationListWS.LocationList_Service(); В LocationListService.UseDefaultCredentials = true;LocationListWS.LocationList[] locations В = LocationListService.ReadMultiple(null, null, 0); dataGridView1.VirtualMode = true; В int offset = 4; В foreach (LocationListWS.LocationList location in locations) В { В dataGridView1.Columns.Insert(offset, new DataGridViewTextBoxColumn()); В dataGridView1.Columns[offset].HeaderText = location.Code; В offset += 1; В } В dataGridView1.CellValueNeeded В += new DataGridViewCellValueEventHandler(dataGridView1_CellValueNeeded); }
Как видим в данном методе происходит считывание записей из таблицы складов в массив объектов. Далее для каждого склада создается столбец.
Кроме того мы изменили режим функционирования элемента управления DataGridView и подписали метод dataGridView1_CellValueNeeded на событие CellValueNeeded.
Ниже приведен код данного метода.
Обратите внимание, что для работы данного кода потребуется расширение веб-службы, созданной на базе карточки товара. Описание данного расширения приведено во второй статье, посвященной веб-службам, из предыдущего выпуска . В данном случае нужно сделать тоже самое: написать програмнмый модуль и включить его в список веб-служб под тем же именем, что и расширяемая веб-служба. Публиковать программный модуль не нужно.
Р?так, расширение веб-службы подключено значит РјРѕР¶РЅРѕ привести РєРѕРґ метода dataGridView1_CellValueNeeded.
private void dataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) { В if (e.ColumnIndex > 3) В { В e.Value = 0; DataGridViewRow row = dataGridView1.Rows[e.RowIndex]; В ItemCardWS.ItemCard item В = row.DataBoundItem as ItemCardWS.ItemCard; В if (item != null) В { В e.Value = ItemCardService.WsCalcfield(item.Key, В dataGridView1.Columns[e.ColumnIndex].HeaderText); В } В } }
Как видим, для всех столбцов с индексом больше 3-х (помним, что в C# нумерация начинается с 0) производится расчет наличия с учетом склада. Код склада берется из названия столбца. По-хорошему надо было переменную locations делать глобальной и смотреть код склада из нее.
Запустим приложение и посмотрим, что получилось.
Не сказал бы, что работает очень шустро. Но работает. В следующей статье мы преобразуем наше приложение в подключаемый компонент и встроим его в ролеориентированный интерфейс.
Метки: Андрей Панько
27 Июнь 2012 в 11:45
Спасибо за статью. Очень полезно.
Но, у меня есть такой вопрос. Предположим у меня в базе 1 500 000 товаров.
Мне нужно эти товары отображать пользователю по 100 товаров ( предположим на одной странице: пользователь нажимает кнопку далее и отображаются следующие 100 товаров). Для вывода 100 товаров на страницу я использую такую конструкцию var ItemList = itemList_Service1.ReadMultiple(null, null, 0).Skip(100 * nom_page).Take(100).ToList();
При использовании ReadMultiple будут выбираться все товарв из базы и потом отображаться только 100 записей. Но, это очень долго.
Каким образом можно заставить выбирать только первые 100 записей ?
27 Июнь 2012 в 14:03
Посмотрите пожалуйста статью http://www.nav4u.ru/archives/345-vvedenie-v-veb-sluzhby-v-microsoft-dynamics-nav-2009-chast-2/
Там как раз про ReadMultiple.
С уважением,
Андрей Панько
2 Июль 2012 в 16:45
Большое спасибо. Не заметил описания последний параметр!