Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / сформировать XML для последующей загрузки в ADO/VBA / 19 сообщений из 19, страница 1 из 1
17.02.2017, 16:55
    #39406779
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
Решаю задачу: быстрая выгрузка данных из веб-сервиса (DataTable) в Excel (VBA, ADODB.Recordset)

Для быстрой загрузки XML в ADODB.Recordset необходимо получить XML следующем виде, включая xmlns, ElementType и AttributeType:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'
	xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'
	xmlns:rs='urn:schemas-microsoft-com:rowset'
	xmlns:z='#RowsetSchema'>
<s:Schema id='RowsetSchema'>
	<s:ElementType name='row' content='eltOnly' rs:CommandTimeout='30'>
		<s:AttributeType name='name_ru' rs:number='1' rs:writeunknown='true'>
			<s:datatype dt:type='string' dt:maxLength='128' rs:maybenull='false'/>
		</s:AttributeType>
		<s:AttributeType name='name_ua' rs:number='1' rs:writeunknown='true'>
			<s:datatype dt:type='string' dt:maxLength='128' rs:maybenull='false'/>
		</s:AttributeType>
		<s:extends type='rs:rowbase'/>
	</s:ElementType>
</s:Schema>
<rs:data>
	<z:row name_ru='Австрия' name_ua='Австрія'/>
	<z:row name_ru='Англия' name_ua='Англія'/>
	<z:row name_ru='Россия' name_ua='Росія'/>
</rs:data>
</xml>



пробовал так - нужные описания не выводит
Код: c#
1.
2.
3.
            DataTable data = new DataTable("phd_data");
            da.Fill(data);
            data.WriteXml(@"c:\qq\1111.xml"); // тут подставлял все значения XmlWriteMode: WriteSchema, IgnoreSchema, DiffGram




загрузка XML в ADO.dataset в VBA выглядит так
Код: vbnet
1.
2.
Set a = New ADODB.Recordset
a.Open xmlDoc



ЗЫ: конечно, при указании XmlWriteMode: WriteSchema описания полей выводятся, но ADO их всё равно не понимает
...
Рейтинг: 0 / 0
17.02.2017, 18:23
    #39406856
Minatavr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
Если не трудно, приложи, фрагмент XML, выгруженный функцией data.WriteXml().

А решением может быть применение XSLT.
...
Рейтинг: 0 / 0
17.02.2017, 18:45
    #39406879
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
http://geekswithblogs.net/AnneBougie/archive/2009/07/02/create-an-adodb-recordset-from-xml.aspx
хотя если структура DataTable статична, я бы схему рекордсета зашил бы в XSLT-шаблон, дальше - сохраняем DataTable в XmlDocument, и применяем к нему XSLT - как-то так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
static void Main(string[] args)
{
  var dt = new DataTable("phd_data");
  // имитация dt.Load
  dt.Columns.Add("name_ru", typeof (string));
  dt.Columns.Add("name_ua", typeof(string));
  foreach(var kvp in new Dictionary<string, string>
    {
      {"Австрия", "Австрія"},
      {"Англия", "Англія"},
      {"Россия", "Росія"}
    })
  {
    var dr = dt.NewRow();
    dr[0] = kvp.Key;
    dr[1] = kvp.Value;
    dt.Rows.Add(dr);
  }
  var xd = new XmlDocument();
  using(var xw = xd.CreateNavigator().AppendChild())
    dt.WriteXml(xw);
  var xslt = new XslCompiledTransform();
  using(var sr = new StringReader(Properties.Resources.Transform))
  using(var xr = XmlReader.Create(sr))
    xslt.Load(xr);
  using(var fs = new FileStream(@"D:\Trash\123.xml", FileMode.Create))
  using(var xw = XmlWriter.Create(fs, new XmlWriterSettings{Indent = true, IndentChars = "  "}))
    xslt.Transform(xd, xw);
  Console.WriteLine("done");
  Console.ReadKey();
}


XSLT (хранится в Properties.Resources.Transform):
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:z="#RowsetSchema">
  <xsl:output method="xml" />
  <xsl:template match="/DocumentElement">
    <xml
      xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
      xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
      xmlns:rs="urn:schemas-microsoft-com:rowset"
      xmlns:z="#RowsetSchema">
      <s:Schema id="RowsetSchema">
        <s:ElementType name="row" content="eltOnly" rs:CommandTimeout="30">
          <s:AttributeType name="name_ru" rs:number="1" rs:writeunknown="true">
            <s:datatype dt:type="string" dt:maxLength="128" rs:maybenull="false" />
          </s:AttributeType>
          <s:AttributeType name="name_ua" rs:number="1" rs:writeunknown="true">
            <s:datatype dt:type="string" dt:maxLength="128" rs:maybenull="false" />
          </s:AttributeType>
          <s:extends type="rs:rowbase" />
        </s:ElementType>
      </s:Schema>
      <rs:data>
        <xsl:apply-templates />
      </rs:data>
    </xml>
  </xsl:template>
  <xsl:template match="phd_data">
    <z:row>
      <xsl:for-each select="node()">
        <xsl:attribute name="{local-name()}">
          <xsl:value-of select="text()" />
        </xsl:attribute>
      </xsl:for-each>
    </z:row>
  </xsl:template>
</xsl:stylesheet>


XML на выходе:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
<?xml version="1.0" encoding="utf-8"?>
<xml
  xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
  xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
  xmlns:rs="urn:schemas-microsoft-com:rowset"
  xmlns:z="#RowsetSchema">
  <s:Schema id="RowsetSchema">
    <s:ElementType name="row" content="eltOnly" rs:CommandTimeout="30">
      <s:AttributeType name="name_ru" rs:number="1" rs:writeunknown="true">
        <s:datatype dt:type="string" dt:maxLength="128" rs:maybenull="false" />
      </s:AttributeType>
      <s:AttributeType name="name_ua" rs:number="1" rs:writeunknown="true">
        <s:datatype dt:type="string" dt:maxLength="128" rs:maybenull="false" />
      </s:AttributeType>
      <s:extends type="rs:rowbase" />
    </s:ElementType>
  </s:Schema>
  <rs:data>
    <z:row name_ru="Австрия" name_ua="Австрiя" />
    <z:row name_ru="Англия" name_ua="Англiя" />
    <z:row name_ru="Россия" name_ua="Росiя" />
  </rs:data>
</xml>
...
Рейтинг: 0 / 0
17.02.2017, 19:37
    #39406910
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
Несколько отчетов в экселе (50)
Под каждый - хранимка в бд возвращает набор строк. Авторизацию в бд на каждого юзверя не дают.

Может, подскажете лучший вариант.
...
Рейтинг: 0 / 0
18.02.2017, 05:45
    #39407013
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
Еще можно приреференсить к проекту ADODB, залить в рекордсет DataTable, и сохранить его в XML: https://www.codeproject.com/Articles/10503/Simplest-code-to-convert-an-ADO-NET-DataTable-to-a
...
Рейтинг: 0 / 0
19.02.2017, 14:01
    #39407417
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
Сон Веры ПавловныЕще можно приреференсить к проекту ADODB, залить в рекордсет DataTable, и сохранить его в XML: https://www.codeproject.com/Articles/10503/Simplest-code-to-convert-an-ADO-NET-DataTable-to-a начал смотреть в эту сторону:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
        private void button2_Click(object sender, EventArgs e)
        {
            ADODB.Connection cn = new ADODB.Connection();
            cn.ConnectionString = @"Provider = Microsoft.Jet.OLEDB.4.0;" + 
                                  @"Data Source=D:\work\c#\WindowsFormsApplication2\WindowsFormsApplication2\bin\Debug\Книга1.xls;" +
                                  @"Extended Properties=Excel 8.0";
            try
            {
                cn.Open();
            }
            catch (Exception ee)
            {
                MessageBox.Show("error [" + ee.Message + "] in [" + ee.Source + "]" + "\n" +
                               cn.ConnectionString);
                return;
            }
            ADODB.Recordset rs = new ADODB.Recordset();
            rs.Open(@"Select * from [Лист1$]", cn, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic, -1);
            string FileName = @"D:\work\c#\WindowsFormsApplication2\WindowsFormsApplication2\bin\Debug\export.txt";
            if (File.Exists(FileName)) File.Delete(FileName);
            rs.Save(FileName, ADODB.PersistFormatEnum.adPersistXML);
            MessageBox.Show("Ok");
            return;

        }

вроде получается
...
Рейтинг: 0 / 0
19.02.2017, 14:59
    #39407439
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
andreymx
Код: c#
1.
rs.Save(FileName, ADODB.PersistFormatEnum.adPersistXML);

подскажите, коллеги
как этот сформированный XML корректно вернуть web-service'ом?
...
Рейтинг: 0 / 0
19.02.2017, 15:14
    #39407441
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
andreymxandreymx
Код: c#
1.
rs.Save(FileName, ADODB.PersistFormatEnum.adPersistXML);

подскажите, коллеги
как этот сформированный XML корректно вернуть web-service'ом?вернуть как результат выполнения метода, имеющего строковый тип, например. или тип байтового массива.
...
Рейтинг: 0 / 0
19.02.2017, 15:15
    #39407442
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
Вместо FileName можно использовать ADODB.Stream, из которого этот байтовый массив легко извлекается.
...
Рейтинг: 0 / 0
19.02.2017, 16:18
    #39407456
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
Строку я думал... Насчёт ресурсоёкости как оно будет?
...
Рейтинг: 0 / 0
19.02.2017, 18:40
    #39407485
Cat2
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
andreymx,

А тебе действительно надо в Эксель?
Можно же в HTML, который эксель скушает потом.
...
Рейтинг: 0 / 0
19.02.2017, 18:44
    #39407487
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
andreymxСтроку я думал... Насчёт ресурсоёкости как оно будет?Ну это ж xml.
Если сохранять в бинарный ADTG, то объем меньше будет и сохранение/загрузка быстрее, нет нужды в/из xml перегонять.
...
Рейтинг: 0 / 0
19.02.2017, 18:50
    #39407489
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
Cat2andreymx,

А тебе действительно надо в Эксель?
Можно же в HTML, который эксель скушает потом.мне из веб-сервиса в эксель в рекордсет данные перегнать. Буду рад хорошему примеру
...
Рейтинг: 0 / 0
20.02.2017, 06:11
    #39407579
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
andreymxначал смотреть в эту сторону:
вроде получается
Какая-то операция на гланды через то место, куда никогда не заглядывает солнце. Файл экселя через рекордсет загнать в XML, чтобы XML отдать веб-сервисом, чтобы клиент снова загнал XML в рекордсет, и от рекордсета снова получил Excel? Начать можно с того, что если в ваших экселях нет эксклюзивных свистелок от версии 2007 и выше, то файл экселя прекрасно сохраняется в свой собственный XML (SpreadsheetML), и прекрасно, бех каких-либо лишних телодвижений, открывает такой XML. Более того, для генерации таких XML вовсе не обязателен сам Excel - достаточно входных данных в виде XML (такие данные может предоставлять, например, запрос от SQL Server или от оракла)+XSLT - у нас энное количество сервисов так генерит вложения для почтовых рассылок по результатам своей отработки. Краткий пример по формированию такого XML можно посмотреть здесь .
...
Рейтинг: 0 / 0
20.02.2017, 08:25
    #39407598
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
Эксель был приведён только как пример источника данных, т.к. дома у меня других нет.
А задача - передать набор данных из веб-сервиса в эксель. В рекордсет.
...
Рейтинг: 0 / 0
20.02.2017, 12:02
    #39407725
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
Веб-сервис твой?
Файл экселя твой?
Рекордсет нужен для экселевского CopyFromRecordset?
...
Рейтинг: 0 / 0
20.02.2017, 13:33
    #39407781
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
AntonariyВеб-сервис твой?
Файл экселя твой?
Рекордсет нужен для экселевского CopyFromRecordset?да
Да
И для этого тоже
...
Рейтинг: 0 / 0
20.02.2017, 17:26
    #39408012
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
Самый простой способ имхо

на сервере создать "универсальный обработчик" (*.ashx)

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
    public class Handler1 : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            ADODB.Connection cn = new ADODB.Connection();
            cn.ConnectionString = @"Provider";
            cn.Open();

            ADODB.Recordset rs = new ADODB.Recordset();
            rs.Open(context.Request.QueryString["sql"], cn, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic, -1);

            ADODB.Stream st = new ADODB.Stream();
            st.Type = ADODB.StreamTypeEnum.adTypeBinary;
            rs.Save(st, ADODB.PersistFormatEnum.adPersistADTG);
            st.Position = 0;

            context.Response.ContentType = "application/octet-stream";
            context.Response.BinaryWrite(st.Read());
        }
    }


На клиенте:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Dim http As New MSXML2.XMLHTTP
Dim st As New ADODB.Stream
Dim rs As New ADODB.Recordset

    http.Open "get", "http://localhost/Handler1.ashx?sql=select * from $Лист1", False
    http.send
    
    st.Type = adTypeBinary
    st.Open
    st.Write http.responseBody
    st.Position = 0
    
    rs.Open st
...
Рейтинг: 0 / 0
20.02.2017, 17:52
    #39408027
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сформировать XML для последующей загрузки в ADO/VBA
Спасибо, поклацаю
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / сформировать XML для последующей загрузки в ADO/VBA / 19 сообщений из 19, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]