Реализация матричной формы с помощью веб-служб

Постоянные читатели наверняка заметили, что написав одну статью по некой теме я редко могу сдержать графоманские позывы. Это часто ведет к появлению целого цикла статей посвященного одной тематике. Так было с отчетами , с подключаемыми компонентами , теперь настал черед веб-служб, знакомство с которыми мы начали в предыдущем выпуске .

Прошлый раз мы остановились на создании приложения, которое демонстрировало возможности по работе с веб-служами, а также отображало остатки по товарам. Последним аккордом было создание столбца отображающего информацию о наличии товаров на Синем складе .

Уже догадались к чему я клоню?

Да, да. Я тоже подумал о создании матричной формы.

Как известно РІ версии NAV 2009 СЃ матричными формами есть проблемы. Даже так. Р?значально РІ Dynamics NAV 2009 матричные формы перестали поддерживаться Рё были заменены недружелюбными поделками РЅР° базе страниц (Page). Хотя СЏ Рё РЅРµ являюсь фанатом матричных форм, однако волею СЃСѓРґСЊР±С‹ внес некий вклад РІ смягчение сложившейся ситуации:

Но никогда не следует останавливаться на достигнутом и сейчас мы попробуем реализовать матричную форму с помощью веб-служб.

Для начала создадим простое приложение считывающее записи из таблицы 27 Item. Этом посвящена статья из предыдущего выпуска , рекомендую с ней ознакомиться перед тем как приступать к чтению настоящей статьи.

Вот что должно получиться.

Приложение изспользующее веб-сервис ItemCard, опубликованный из Dynamics NAV

Это было работающее приложение. А вот весь написанный для этого приложения код:

Код для приложения использующего веб-службы

Не забываем, что нужно добавить Web Reference, DataGridView и BindingSource. Помним, что веб-служба должна быть опубликована, а служба Microsoft Dynamics NAV Business Web Services – запущена.

Дизайнер формы приложения, использующего веб-службы Dynamics NAV 

Ну что ж. Подготовительный этап завершен. Перейдем к созданию добавленной стоимости.

Так как мы хотим создать матричную форму, то и действовать надо соответственно. Для начала вспомним о том, что классические матричные формы используют две связанные таблицы – одна для строк, другая для столбцов. Значит нам нужно поступить также.

Для этого опубликуем еще одну веб-службу. В дополнение к товарам, мы опубликуем еще и перечень складов – это страница 15. Назовем службу LocationList:

 Публикация веб-службы из ролеориентированного клиента

Далее добавим ссылку на эту веб-службу в наше приложение.

Add Web Reference

Обратите внимание, что в отличие от веб-службы на базе карточки товара, список складов имеет меньше доступных методов. Данная веб-служба не предоставляет возможности ни создать, ни удалить, ни изменить склад. Только чтение.

Причина кроется в свойствах самой страницы, на базе которой создана веб-служба.

Свойства страницы Location List

Как видно на рисунке, для данной страницы в свойстве 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 делать глобальной и смотреть код склада из нее.
Запустим приложение и посмотрим, что получилось.

Матричная форма на базе веб-служб Dynamics NAV

Не сказал бы, что работает очень шустро. Но работает. В следующей статье мы преобразуем наше приложение в подключаемый компонент и встроим его в ролеориентированный интерфейс.

Метки:



Комментариев: 3

  1. Art пишет:

    Спасибо за статью. Очень полезно.
    Но, у меня есть такой вопрос. Предположим у меня в базе 1 500 000 товаров.
    Мне нужно эти товары отображать пользователю по 100 товаров ( предположим на одной странице: пользователь нажимает кнопку далее и отображаются следующие 100 товаров). Для вывода 100 товаров на страницу я использую такую конструкцию var ItemList = itemList_Service1.ReadMultiple(null, null, 0).Skip(100 * nom_page).Take(100).ToList();
    При использовании ReadMultiple будут выбираться все товарв из базы и потом отображаться только 100 записей. Но, это очень долго.
    Каким образом можно заставить выбирать только первые 100 записей ?

  2. apanko пишет:

    Посмотрите пожалуйста статью http://www.nav4u.ru/archives/345-vvedenie-v-veb-sluzhby-v-microsoft-dynamics-nav-2009-chast-2/
    Там как раз про ReadMultiple.

    С уважением,
    Андрей Панько

  3. Art пишет:

    Большое спасибо. Не заметил описания последний параметр!

Оставьте свой отзыв!