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

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

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

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

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

Как известно в версии 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 пишет:

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

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