(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Excel как WEB-клиент

Источник: vbrussian
Файфель Б.Л.

Наверное, каждый WEB-разработчик сталкивался с проблемой построения графиков и диаграмм в браузере. Это и сейчас (несмотря на бурное развитие средств разработки) остается серьезной проблемой. Дело в том, что отцы-основатели HTML не предусмотрели достаточно внятных средств для отображения презентационной графики. Нет, готовую картинку отобразить легко. Но если ее нужно строить динамически... Возможностей не так много: можно строить картинку на сервере и передавать клиенту либо в виде файла, либо в виде графического контента; а можно передавать данные для построения графика/диаграммы клиенту, и картинку строить на клиентском компьютере.
 
Каждый из этих подходов имеет свои плюсы и минусы.
 
При построении картинки на сервере нужно разработать самому или где-то взять (купить!) готовый серверный компонент. 
При построении картинки на стороне клиента графический компонент придется внедрять в html-страницу. При этом нужно, чтобы компонет присутствовал у клиента. А если компонента у клиента нет, потребуется обеспечить его инсталляцию через WEB-интерфейс. В этом случае компонент желательно подписать. Клиенту при инсталляции будут задаваться лишние вопросы, а это отпугивает...
 
Предлагаю для отображения графики использовать Excel. Это не так абсурдно, как кажется на первый взгляд. 
 
В составе Excel есть великолепный мастер диаграмм. Мы получаем с WEB-сервера только числовые данные, а нужную нам диаграмму или график строит Excel. При этом внешний вид (тип диаграммы, ее конкретные настройки, размеры и т.д.) мы задаем сами, и всегда можем изменить.
Поскольку WEB-сервер только генерирует поток числовых данных (это в десятки раз меньший объем, чем графическая картинка!), нагрузка на WEB-сервер и сеть значительно снижается, что тоже неплохо.
 
Хотите попробовать? Не пожалеете!
 
Начнем с сервера. Автор является поклонником Microsoft-технологий. В данном случае мы будем использовать ASP для серверного сценария и Access для хранения данных. 
Создаем пустую Access-ную базу; файл назовем "myBase.mdb". Занесем в эту базу данные для построения трех графиков:
 
-y=sin(x);
-y=x^2;
-y=Exp(-0.2*x)*Sin(5*x)
 
Для этого создадим в базе таблицу (назвав ее, скажем, Dat), у которой будут четыре поля x, y1, y2 и y3 (все типа Float). Затем заполним таблицу данными. Все это делается следующим VBS-скриптом:

'----- Получим имя текущей директории

Tmp=Cstr(WScript.ScriptFullName)
       
 l=Len(Tmp)

 For i=l to 1 Step -1

      If mid(Tmp,i,1)="\" then

         HomeDir=Left(Tmp,(i-1))
         Exit For

       End if

 Next

 '----- Создадим ADO-соединение и recordset

 Set Conn = CreateObject("ADODB.Connection")

 Set RS = CreateObject("ADODB.Recordset")

 DSNName = "DRIVER=Microsoft Access Driver (*.mdb);DBQ="
 DSNName = DSNName & HomeDir & "\mybase.mdb"
 Conn.Open DSNName

 '------ Проверим, присутствует ли наша таблица в базе

 flgPresent=False 

 Set QS = Conn.OpenSchema(20)
    
 Do While Not QS.EOF

     TblName = Cstr(QS.Fields("TABLE_NAME").Value)

     If Ucase(TblName)="DAT" then
         flgPresent=True
         Exit Do
     End if

     QS.MoveNext

 Loop

 QS.Close

 Set QS=Nothing 

 If Not flgPresent then  '------ Если таблицы еще нет - создаем

      SQL="create table Dat (x Float, y1 Float, y2 Float, y3 Float)"  

      RS.Open SQL, Conn, 3, 3

 Else                           '------ А если есть - чистим

      SQL="Delete from Dat"

      RS.Open SQL, Conn, 3, 3

 End if

'------ Заполним таблицу

For xx=0 to 10 step 0.01               ' диапазон и шаг построения

      y1=Sin(xx)                               ' формулы
      y2=xx^2                                  ' формулы
      y3=Exp(-0.2*xx)*Sin(5*xx)  ' формулы

     aX=Cstr(xx)

     aY1=Cstr(y1)
     
     aY2=Cstr(y2)
     
     aY3=Cstr(y3)
     
      SQL="insert into Dat Values (" & Cstr(aX) & "," & Cstr(aY1) & "," & _ 
                Cstr(aY2) & "," & Cstr(aY3) & ")"

     RS.Open SQL, Conn, 3, 3

Next

Conn.Close
Set Conn=Nothing 

MsgBox "OK!"


 
Создадим на нашем WEB-сервере виртуальную директорию, скопируем в нее пустую базу (mybase.mdb) и приведенный выше скрипт (сохранив его в текстовом файле creatable.vbs). Теперь исполним скрипт. Если появилось сообщение "OK!", значит таблица наполнена.
Займемся ASP-сценарием.
Это должен быть простой ASP-скрипт, который берет на вход единственный параметр NG - номер графика (число 1, 2 или 3), а возвращает выходной поток следующего вида:
 
N/
x, y/
x, y/
 
...
 
Здесь N - число точек, x - очередное значение аргумента; y - очередное значение функции. Символ "/" - это разделитель групп.
 
У человека мало-мальски знакомого с ASP, текст сценария никаких затруднений не вызовет:

<%

     '--- Получим номер графика. Если он неверен - принудительно
     '--- ставим 1

     nGr=Request("NG") 

     if nGr = "" then nGr=1

     If (nGr > 3) Or (nGr < 1) then nGr=1

     '--- Создаем соединение и recordset

     Set Conn = Server.CreateObject("ADODB.Connection")

     Set RS = Server.CreateObject("ADODB.Recordset")

     DSNName = "DRIVER=Microsoft Access Driver (*.mdb);DBQ="
     DSNName = DSNName & Server.MapPath("./mybase.mdb")

     '--- Открываемся...

     Conn.Open DSNName

     '--- Определим число точек

     SQL="Select count(*) As N From Dat"

     RS.Open sql, Conn, 3, 3

     N=Cstr(RS("N"))

     RS.Close

     '--- Передадим число точек клиенту

     Response.Write N & "/"

     '--- Строим строку запроса

     SQL="Select x,y" & Cstr(nGR) & " From Dat order by x"

     '--- Исполняем ее...

     RS.Open sql, Conn, 3, 3

     '--- Возвращаем ответ клиенту

     Do while not RS.EOF

        x =RS("x")
        y=RS("y" & Cstr(nGr))

        Response.Write x & "/" & y & chr(10)

        RS.MoveNext 

     Loop

     Conn.Close

     Set Conn=Nothing

%>


 
Назовем наш сценарий gety.asp. Предполагаем, что наша база находится в той же директории, что и скрипт. Это, разумеется, не слишком безопасно, но мы строим учебный пример и хотим проверить механизм работы.
Чтобы убедиться, что сценарий работает, зайдем на наш сайт обычным браузером, набрав в строке адреса:
 
http://Имя_нашего_сайта/Имя_Вирт_директории/gety.asp?NG=1
 
Ответ должен быть примерно таким:
 

 
Получилось? Отлично! Сайт готов. Теперь займемся клиентской частью. Для этого нам потребуется Excel (97-й или 2000-й) и специальный компнент MSINET.OCX. Если на Вашем компьютере установлен VB версии 5 или 6 в Professional/Enterprise-редакции, то, скорее всего, этот компонент у Вас уже есть. Если же это не так, можете скачать приложение к статье в виде архива. В этом архиве содержится и MSINET.OCX.
 

Замечание для тех, у кого компнента не было.


Файл MSINET.OCX нужно извлечь из архива, скопировать в Вашу системную директорию и зарегистрировать. Регистрация выполняется так. Находясь в системной директории ..\Windows\System32, выполняем команду:
 
regsvr32 MSINET.OCX
 
Если появится сообщение об успешной регистрации - все хорошо. Если появится сообщение об ошибке - скорее всего у Вас отсутствует run-time библиотека Msvbvmxx.Dll (xx - номер версии). Хотя, трудно представить, чтобы у посетителей сайта vbrussain.com не было этой библиотеки...
Итак, компонент у нас установлен. Запускаем Excel. С помощью мастера диаграмм размещаем на первом листе диаграмму, подходящего для графика типа. Область данных для диаграммы спозиционируем за пределы видимой части листа (в колонки AA и AB, чтобы не мешала). 
Слева от диаграммы разместим четыре надписи: три соответствуют трем графикам, а четвертая предназначена для очистки области диаграммы. Все это выглядит примерно так:
 

 
Теперь заходим в редактор VBA и добавляем к проекту форму. Называем форму frmWeb, устанавливаем произвольные размеры, и размещаем на форме компонент Inet. Вид и размеры формы совершенно не важны: форма используется только как контейнер для компонента Inet и никогда не будет отображаться.
У Вас нет компонента Inet в палитре? Нужно подключить. Это делается так. Щелкаем правой клавишей мыши на панели элементов управления. В появившемся контекстном меню выбираем "Дополнительные компоненты". 
 

 
Появится окно дополнительных компонентов. Выбираем в нем "Microsoft Internet Transfer Control", ставим крестик и нажимаем ОК:
 

 
После этого у Вас в палитре элементов управления появится новый компонент с иконкой:
 

 
Кладем этот компонент на нашу форму. Далее нужно написать совсем немного кода. В область листа вставляем главную процедуру приема данных:
 

Sub AcceptData(Url As String)

Dim Buffer()  As Byte
Dim XX()      As Double
Dim YY()      As Double
        
       Application.ScreenUpdating = False          ' Запретим ненужное мигание
        
       Columns("AA:AB").Select                            '  Чистим область данных диаграммы
       Selection.ClearContents
        
       Buffer = frmWeb.Inet1.OpenURL(Url, 1)   ' Получаем данные от WEB-сервера
 
       Nb& = UBound(Buffer, 1) 
 
       If Nb&=-1 then
           Msgbox "Сервер не отвечает!"
           Exit Sub
       End if

       '::: Выделяем к-во точек
    
       Tmp$ = ""
    
       ii& = 0
    
       Do
           S$ = Chr$(Buffer(ii&))
           ii& = ii& + 1
           If S$ = "/" Then Exit Do
         Tmp$ = Tmp$ + S$
    Loop
    
    BSize& = Val(Tmp$)
    
    '::: Размещаем массив
    
    ReDim XX(1 To BSize&) As Double
    ReDim YY(1 To BSize&) As Double
    
    '::: Извлекаем данные
    
    kk& = 0
    
    Do
    
       If ii& > Nb& Then Exit Do
    
       cX$ = ""
    
       Do
     
          S$ = Chr$(Buffer(ii&))
          ii& = ii& + 1
          If ii& > Nb& Then Exit Do
          If S$ = "/" Then Exit Do
          If S$ = "," Then S$ = "."
          cX$ = cX$ + S$
          
       Loop
    
      If ii& > Nb& Then Exit Do

       cY$ = ""
    
       Do
     
          S$ = Chr$(Buffer(ii&))
          ii& = ii& + 1
          If ii& > Nb& Then Exit Do
          If S$ = Chr$(10) Then Exit Do
          If S$ = "," Then S$ = "."
          cY$ = cY$ + S$
          
       Loop
    
      If ii& > Nb& Then Exit Do

       kk& = kk& + 1
    
       XX(kk&) = Val(cX$)
       YY(kk&) = Val(cY$)
    
    Loop

    '::: Размещаем данные

    For ii& = 1 To kk&
        Sheets(1).Cells(ii&, 27).Value = XX(ii&)
        Sheets(1).Cells(ii&, 28).Value = YY(ii&)
    Next ii&

    '::: Заносим их в диаграмму

    ActiveSheet.ChartObjects(1).Activate

    ActiveChart.SetSourceData _ 
   Source:=Sheets("Лист1").Range("AB1:AB" + CStr(kk&)), PlotBy:=xlColumns
                
    ActiveChart.SeriesCollection(1).XValues = "=Лист1!R1C27:R" + _ 
    CStr(kk&) + "C27"
    
    Sheets(1).Range("A1").Select

    Application.ScreenUpdating = True

End Sub


 
Немного комментариев. Эта процедура имеет единственный входной параметр - URL-строку запроса. У компонента "Microsoft Internet Transfer Control" мы используем метод OpenURL. Метод имеет два параметра: собственно адрес в URL-нотации и тип данных. Результат возвращается в байтовом массиве. Причем, размер масива устанавливается автоматически. Это очень удобно. 
Получив ответ, следует первым делом определить количество принятых байтов. Это делает оператор Nb& = UBound(Buffer, 1). Если Nb& окажется равным -1, значит WEB-сервер не отвечает. А дальше нужно выделить из ответа число точек и сами точки. Как можно видеть из текста процедуры, автор помещает их в рабочие массивы. А можно было бы сразу заносить в область данных диаграммы (колонки AA и AB).Обратите внимание и на то, что для преобразования числа с плавающей точкой из символьного типа в двоичный используется функция VAL. А она не воспринимает запятую в качестве разделителя целой и дробной части. Поэтому приходится проверять наличие запятой и заменять ее точкой. (Запятая может появиться, если на WEB-сервере системный разделитель - запятая).
Осталось только добавить четыре тривиальные процедурки к этому коду:
 

Public Sub drawSin()

       AcceptData "http://bob/Graph/gety.asp?NG=1"

End Sub

Public Sub drawSQ()

       AcceptData "http://bob/Graph/gety.asp?NG=2"

End Sub

Public Sub drawExp()

       AcceptData "http://bob/Graph/gety.asp?NG=3"

End Sub

Public Sub Clear()

       Columns("AA:AB").Select
       Selection.ClearContents
       Range("A1").Select

End Sub


 
Первые три обеспечивают построение графиков, а последняя служит для очистки области диаграммы. Возвращаемся на главный лист и назначаем надписям процедуры-события: 
 
-надписи "Y=Sin(x)" - DrawSin
-надписи "Y=x^2"  - DrawSq
-надписи "Колебания" - DrawExp
-надписи "Очистить" - Clear.
 
Теперь щелкнем, например, по надписи "Колебания":
 

 
Неплохо? По-моему, тоже...
 
Механизм ясен. В приведенном примере мы берем данные, уже "сидящие" в таблице. Но ничего не мешает разработать asp- (или php-) скрипты, которые будут строить новые данные для отображения у клиента. В простейшем случае это может выглядеть хотя бы так: в базе находятся данные, например, об объеме продаж за 10 лет (день за днем). При запросе передается интервал дат (дата начала и дата конца интервала). Скрипт выбирает из таблицы данные, относящиеся к запрошенному интервалу, и возвращает их клиенту. А на клиентской стороне строится диаграмма. Можно даже на клиентской стороне формировать строки SQL-запросов, и передавать их на сервер. А сервер вернет результат, из которых Excel построит диаграмму. 
Создавайте таблицы с данными произвольной сложности, конструируйте нужные SQL-запросы, и наслаждайтесь отличной презентационной графикой Excel! Если нужно отображать не только графики, а еще и текст - нет проблем. Текст можно точно так же извлечь из базы, передать клиенту и отобразить потом в ячейках листа или в надписях. На сервере можно использовать всю мощь SQL (включая хранимые процедуры). 
Кроме того, обязательно нужно предусмотреть обработку серверных ошибок. Это не очень сложно. Переименуйте на сервере файл gety.asp, войдите в редактор VBA, поставьте точку останова на оператор Nb& = UBound(Buffer, 1), и попытайтесь построить любой график. В байтовый массив будет занесено стандратное сообщение (типа 404). Можно, привязавшись к характерным контекстам этого сообщения, распознать ошибку и выдать пользователю сообщение типа "Страница не найдена". 
Описанный подход автор использует в корпоративной сети в течение ряда лет. Но что мешает использовать описанную технику в глобальном Интернете?
В прилагаемый пример автор вставил ссылку на реальный Internet-сервер. Можете убедиться, что пример будет работоспособным (только не забудьте сначала установить Internet-соединение!)
 
Полный текст примера и компонент MSINET.OCX можно скачать здесь.
 
Успехов!

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 19.07.2012 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Oracle Database Personal Edition Named User Plus Software Update License & Support
IBM Domino Messaging Server Processor Value Unit (PVU) License + SW Subscription & Support 12 Months
Quest Software. TOAD for SQL Server Xpert Edition
Delphi Professional Named User
Microsoft 365 Business Basic (corporate)
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
Программирование в AutoCAD
eManual - электронные книги и техническая документация
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100