Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.07.2012, 10:29   #1
Evgeny86Ru
Новичок
Джуниор
 
Регистрация: 01.07.2012
Сообщений: 8
По умолчанию Генерация XML Delphi

Код:
..
type

Array_of_record_news = Record
 title : pChar;
 body  : pChar;
 //   title : string[200];
 // body  : string[200];
end;

..
procedure TForm1.Button3Click(Sender: TObject);
var
  xml_news : TXMLDocument;
 //i,k,c: integer;
  Excel_news: OleVariant;
  s,dt: string;
begin

  c:=1;
  setlength(news_r,c);

   // создаем объект и указываем путь к файлу
   Excel_news := CreateOleObject('Excel.Application');
   Excel_news.Workbooks.Open['d:\news.xls'];
   // узнаем сколько строчек заполнено в шаблоне
   c:=Excel_news.ActiveSheet.UsedRange.Rows.Count;


   dt := Excel_news.Cells[2, 1];
   for I := 2 to c do
      begin
    //   news_r[i].title := Excel_news.Cells[i, 2];
        news_r[i].title := PChar(VarToStr(Excel_news.Cells[i, 2]));
           ShowMessage(news_r[i].title);
    //   news_r[i].body := Excel_news.Cells[i, 3];
            news_r[i].body := PChar(VarToStr(Excel_news.Cells[i, 3]));
           ShowMessage(news_r[i].body);







      end;
  Excel_news.ActiveWorkbook.Close;

 // ShowMessage(news_r[2].title);


// блок заполнения xml документа.
  Xml_news := TXMLDocument. Create (nil);
    xml_news.XML.Clear;
      xml_news.Active:=true;
        xml_news.Encoding:='UTF-8';

with Xml_news do
  begin
    with AddChild ('today_news') do
      begin
        SetAttributeNS('date','',dt);
        for I := 2 to c  do
          begin

            with AddChild('news') do
              begin

                     ChildValues ['news_header'] :=news_r[i].title;
                     ChildValues ['news_body'] := news_r[i].body;
              end;
          end;
      end;

   end;
     Xml_news. SaveToFile ('d:\news.xml');
  end;
доброго дня, помогите пожалуйста разобраться с проблемой. Задача стоит следующая: Необходимо считать из эксель новости в формате заголовок и сама новость. Поместить в массив типа рекорд и потом сформировать xml. До сего момента использовался тип данных для забираемых значений из эксель string. Все работало нормально.Но при данном типе идет ограничение по количеству символов в переменной (вроде 256). Новости зачастую бывают гораздо больше. Потому решил попробовать тип pChar. как видно из кода, в массив я смог загрузить весь объем текста, но затык получился в формировании самого xml.(выделено жирным) Помогите советом, как сформировать данный xml.




________
Код нужно оформлять по правилам:
тегом [CODE]..[/СODE] (это кнопочка с решёточкой #)
Не забывайте об этом!
Модератор.

Последний раз редактировалось Serge_Bliznykov; 01.07.2012 в 15:19.
Evgeny86Ru вне форума Ответить с цитированием
Старый 01.07.2012, 11:04   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

1. В record можно title и body объявить как string без длины и любые длинные обработаются
2. если уж PChar, то
Код:
ChildValues ['news_header'] :=String(news_r[i].title);
ChildValues ['news_body'] := String(news_r[i].body);
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 01.07.2012, 12:18   #3
Evgeny86Ru
Новичок
Джуниор
 
Регистрация: 01.07.2012
Сообщений: 8
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
1. В record можно title и body объявить как string без длины и любые длинные обработаются
2. если уж PChar, то
Код:
ChildValues ['news_header'] :=String(news_r[i].title);
ChildValues ['news_body'] := String(news_r[i].body);
я попробовал сделать как Вы сказали, ошибка при старте ушла, но при нажатии на кнопу выскакивает другая:
Цитата:
Module Load: RpcRtRemote.dll. No Debug Info. Base Address: $717B0000. Process last.exe (2776)
Thread Start: Thread ID: 4256. Process last.exe (2776)
Thread Start: Thread ID: 3672. Process last.exe (2776)
Thread Start: Thread ID: 2992. Process last.exe (2776)
Module Load: KERNEL32.dll. No Debug Info. Base Address: $027F0000. Process last.exe (2776)
Module Unload: KERNEL32.dll. Process last.exe (2776)
First chance exception at $76D7B9BC. Exception class EAccessViolation with message 'Access violation at address 004044BD in module 'last.exe'. Read of address 00650076'. Process last.exe (2776)

Последний раз редактировалось Evgeny86Ru; 01.07.2012 в 12:23.
Evgeny86Ru вне форума Ответить с цитированием
Старый 01.07.2012, 14:23   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Сделайте так, как в пункте 1 предложил. С PChar не так просто, там память нужно выделять под каждую строку при сохранении в массив рекордов, потом освобождать
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 01.07.2012, 14:42   #5
Evgeny86Ru
Новичок
Джуниор
 
Регистрация: 01.07.2012
Сообщений: 8
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Сделайте так, как в пункте 1 предложил. С PChar не так просто, там память нужно выделять под каждую строку при сохранении в массив рекордов, потом освобождать
Код:
unit XML;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, xmldom, XMLIntf, msxmldom, XMLDoc, StdCtrls, ComObj, DB, ADODB,
  Grids,
  DBGrids, Clipbrd, DateUtils;

type

  Array_of_record_news = Record
    title: string[200];
    body: string[200];
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    XMLDocument1: TXMLDocument;
    Edit1: TEdit;
    Button2: TButton;
    Button3: TButton;
    procedure Button3Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  r: array of Array_of_record; // массив записей
  news_r: array of Array_of_record_news;
  i, k, c: integer;

implementation

{$R *.dfm}

// ====================================

procedure TForm1.Button3Click(Sender: TObject);
var
  xml_news: TXMLDocument;
  // i,k,c: integer;
  Excel_news: OleVariant;
  dt: string;
begin

  c := 1;
  setlength(news_r, c);

  // создаем объект и указываем путь к файлу
  Excel_news := CreateOleObject('Excel.Application');
  Excel_news.Workbooks.Open['d:\news.xls'];
  // узнаем сколько строчек заполнено в шаблоне
  c := Excel_news.ActiveSheet.UsedRange.Rows.Count;
  ShowMessage(IntToStr(c));
  for i := 2 to c do
  begin
    ShowMessage(Excel_news.Cells[i, 2]);
  end;




  // dt := Excel_news.Cells[2, 1];

  for i := 2 to c do
  begin
     news_r[i].title := Excel_news.Cells[i, 2];
    // news_r[i].title := pChar(VarToStr(Excel_news.Cells[i, 2]));
     news_r[i].body := Excel_news.Cells[i, 3];
    // news_r[i].body := pChar(VarToStr(Excel_news.Cells[i, 3]));

  end;
  Excel_news.ActiveWorkbook.Close;

  // блок заполнения xml документа.
  xml_news := TXMLDocument.Create(nil);
  xml_news.XML.Clear;
  xml_news.Active := true;
  xml_news.Encoding := 'UTF-8';

  with xml_news do
  begin
    with AddChild('today_news') do
    begin
      SetAttributeNS('date', '', dt);
      for i := 2 to c do
      begin
        with AddChild('news') do
        begin
           ChildValues ['news_header'] :=news_r[i].title;
           ChildValues ['news_body'] := news_r[i].body;
        end;
      end;
    end;

  end;
  xml_news.SaveToFile('d:\news.xml');
end;

end.
вот полный код . Не получилось использовать string в чистом его виде.
Он считывать с экселя считывает, а вот записывать в переменные не хочет. В этом листинге убрав [200] начинает ругаться на неверный адрес. В чем может быть проблема?




________
Код нужно оформлять по правилам:
тегом [CODE]..[/СODE] (это кнопочка с решёточкой #)
Не забывайте об этом!
Модератор.

Последний раз редактировалось Serge_Bliznykov; 01.07.2012 в 15:20.
Evgeny86Ru вне форума Ответить с цитированием
Старый 01.07.2012, 14:49   #6
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

1.
Код:
Array_of_record_news = Record
title: string;
body: string;
end;
2. setlength(news_r, c); где стоит? Память выделена только под один элемент массива, а нужно под сколько?
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 01.07.2012, 14:56   #7
Evgeny86Ru
Новичок
Джуниор
 
Регистрация: 01.07.2012
Сообщений: 8
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
1.
Код:
Array_of_record_news = Record
title: string;
body: string;
end;
2. setlength(news_r, c); где стоит? Память выделена только под один элемент массива, а нужно под сколько?
при этой записи
title: string;
body: string;

выдает ошибку неверного адрес

при этой записи
title: string[200];
body: string[200];

ошибок не возникает и файл формируется.

setlength(news_r, c) переставил после определения количества строк в экселе, что потом и есть размерность массива. но не помогло.

получ вот так
Код:
  // создаем объект и указываем путь к файлу
  Excel_news := CreateOleObject('Excel.Application');
  Excel_news.Workbooks.Open['d:\news.xls'];
  // узнаем сколько строчек заполнено в шаблоне
  c := Excel_news.ActiveSheet.UsedRange.Rows.Count;

   setlength(news_r, c);


  // dt := Excel_news.Cells[2, 1];

  for i := 2 to c do
  begin
     news_r[i].title := Excel_news.Cells[i, 2];
     news_r[i].body := Excel_news.Cells[i, 3];
  end;
  Excel_news.ActiveWorkbook.Close;

Последний раз редактировалось Evgeny86Ru; 01.07.2012 в 15:23.
Evgeny86Ru вне форума Ответить с цитированием
Старый 01.07.2012, 15:23   #8
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

В news_r элементы нумеруются с 0 до c-1 и ваш цикл вывалит ошибку по памяти при присвоении в news_r[с]. В Excel не помню с 0 или 1
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 01.07.2012, 15:42   #9
Evgeny86Ru
Новичок
Джуниор
 
Регистрация: 01.07.2012
Сообщений: 8
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
В news_r элементы нумеруются с 0 до c-1 и ваш цикл вывалит ошибку по памяти при присвоении в news_r[с]. В Excel не помню с 0 или 1
то есть заполнение массива должно происходить так?
Код:
  c := Excel_n.ActiveSheet.UsedRange.Rows.Count;
  setlength(r, c);
  for i := 0 to c - 1 do
  begin
     news_r[i].title := Excel_news.Cells[i +2, 2];
     news_r[i].body := Excel_news.Cells[i + 2, 3];
  end;
  Excel_n.ActiveWorkbook.Close;

Последний раз редактировалось Evgeny86Ru; 01.07.2012 в 15:56.
Evgeny86Ru вне форума Ответить с цитированием
Старый 01.07.2012, 16:03   #10
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Если в Excel нумерация с 1, то так как ниже. Если с 0, то +1 убрать. Если самая первая строка из Excel не нужна то цикл с 1 (и соответственно строчка с идексом 0 не будет заполнена, это нужно помнить дальше)
Код:
  c := Excel_n.ActiveSheet.UsedRange.Rows.Count;
  setlength(r, c);
  for i := 0 to c - 1 do
  begin
     news_r[i].title := Excel_news.Cells[i +1, 2];
     news_r[i].body := Excel_news.Cells[i + 1, 3];
  end;
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Генерация пароля в Delphi 2010 Kreadlling Общие вопросы Delphi 1 05.04.2012 14:14
Генерация лабиринта в Delphi dancer1 Помощь студентам 4 21.02.2012 07:09
Генерация программного кода по xml файлу liosha Помощь студентам 0 21.03.2011 12:24
Генерация XML файла dekameron PHP 1 31.07.2010 22:17
генерация id в xml файле kate158 Помощь студентам 2 07.08.2008 09:31