1 (edited by savage 2014-10-06 04:09:39)

Topic: [Решено] импорт данных из excel в базу данных

Вечер добрый,

1. Есть база данных Курсов валют с полями:
date (дата), skv (наименование валюты - через связь со справочником валют), kurs (курс валюты)

2. Есть форма ввода frmCurrancy с возможностью ручного ввода курсов валют. Форма содержит кнопку bImport

3. Вопрос - есть ли способ симпортировать через кнопку bImport в данную базу курсы валют из файла excel, где курсы представлены в виде:
дата, валюта, курс (см. приаттаченный файл)? Если есть, то куда "рыть"?

4. Защита от дублирования уже введенных курсов. Имхо, возможно, это потяну и сам

с уважением,

savage

Post's attachments

Attachment icon Currancies.xls 29.5 kb, 702 downloads since 2014-10-03 

Re: [Решено] импорт данных из excel в базу данных

Для реализации импорта, добавил новую функцию для скрипта, пожалуйста скачайте бета версию 1.45
https://www.dropbox.com/s/88lx13h9cw5ro … 5.zip?dl=0


Импортировать непосредственно Excel файл нельзя, поэтому сначала сохраните xls файл как csv (используя Excel)


Пример проекта с реализацией можете скачать по этой ссылке, так же в папке с проектом найдете готовый csv файл который можно импортировать.

Post's attachments

Attachment icon Import CSV.zip 3.85 kb, 1094 downloads since 2014-10-04 

Dmitry.

3 (edited by savage 2014-10-04 18:00:53)

Re: [Решено] импорт данных из excel в базу данных

DriveSoft, при попытке импорта, ругается на неправильные даты. Имхо, некорректный формат представления дат в csv
когда сконвертил свой, все отработало штатно.

спасибо огромное

Re: [Решено] импорт данных из excel в базу данных

Да.. у нас просто разные форматы дат в региональных настройках, поэтому мой csv файл был некорректный относительно ваших региональных настроек.

Dmitry.

Re: [Решено] импорт данных из excel в базу данных

DriveSoft, попробовал встроить проверку на наличие в базе уже введенных курсов (для избежания дублирования) и не получилось.
Посмотрите, плиз, код на предмет ЧЯДНТ:

procedure Form1_Button2_OnClick (Sender: string; var Cancel: boolean);
var
   OpenDialog: TOpenDialog;
   sl: TStringList;
   arrStr: array of string;

   i,c: integer;
   sval,ValuteID: string;
   sDate: string;
begin
     OpenDialog := TOpenDialog.Create(Form1);
     if OpenDialog.Execute then
     begin
          sl := TStringList.Create;
          sl.LoadFromFile (OpenDialog.FileName);


          c := sl.Count - 1;
          for i := 0 to c do
          begin
               arrStr := SplitString(sl[i], ';');

               // date
               if arrStr[0]<>'' then
                  sDate := '"'+ FormatDateTime('yyyy-MM-DD 00:00:00.000', StrToDate(arrStr[0])) + '"'
                  else sDate := 'NULL';

               // id_valute
               ValuteID := SQLExecute ('SELECT id FROM valute WHERE valute LIKE "' + arrStr[1] +'"');
               if ValuteID = '' then ValuteID := 'NULL';

               // value
               arrStr[2] := ReplaceStr(arrStr[2], ',', '.');
               if arrStr[2] = '' then arrStr[2] := 'NULL';

               sval := SQLExecute('SELECT id FROM currency WHERE (date = '''+ sDate + ''') AND (id_valute = ''' +  ValuteID + ''') AND (value = ''' + arrStr[2] + ''') ;');
              
               if sval = '' then
                begin
                  SQLExecute ('INSERT INTO currency (date, id_valute, value) VALUES ('+ sDate +','+ ValuteID +','+arrStr[2] +');');
                end;
                  Form1.Label1.Caption := IntToStr(i) + ' of ' + IntToStr(c);
                  Application.ProcessMessages;
           end;



          sl.Free;
          Form1.TableGrid1.dbUpdate;
     end;
     OpenDialog.Free;
end;


begin

end.

Re: [Решено] импорт данных из excel в базу данных

Вы немного напутали с кавычками в запросе, проверка будет такой

sval := SQLExecute('SELECT id FROM currency WHERE (date = ' + sDate + ') AND (id_valute = ' +  ValuteID + ') AND (value = ' + arrStr[2] + ') ;');
if sval = '' then SQLExecute ('INSERT INTO currency (date, id_valute, value) VALUES ('+ sDate +','+ ValuteID +','+arrStr[2] +');');  
Dmitry.

Re: [Решено] импорт данных из excel в базу данных

Спасибо, все работает.

Re: [Решено] импорт данных из excel в базу данных

DriveSoft, решил немного модернизировать скрипт в сторону проверки на присутствие в базе валюты на заданную дату:
если поиск обнаруживает, что csv - файл содержит курсы, которые уже есть в базе (совпадают дата и тип валюты, курс может быть отличным от того, что в базе), то при прочих равных курсы файла импорта принимаются за более верные и затирают старые значения.

модернизировал скрипт таким образом:

svalute := SQLExecute('SELECT id FROM CurrancyEx WHERE (date = ' + sDate + ') AND (id_Currancy = ' +  ValuteID + ');');
               if svalute = '' then  SQLExecute ('INSERT INTO CurrancyEx (date, id_Currancy, sum) VALUES ('+ sDate +','+ ValuteID +','+arrStr[2] +');');
               if svalute <> '' then
                begin
                  SQLExecute ('DELETE FROM CurrancyEx    WHERE (date = ' + sDate + ') AND (id_Currancy = ' +  ValuteID +');');
                  SQLExecute ('INSERT INTO CurrancyEx (date, id_Currancy, sum) VALUES ('+ sDate +','+ ValuteID +','+arrStr[2] +');');
                end;

DriveSoft, посмотрите, плиз, на оптимальность кода, т.к., возможно ,есть функция, которая сразу позволяет сделать вставку новой записи с заменой старой по совпадению ряда полей.

Re: [Решено] импорт данных из excel в базу данных

попробуйте так

svalute := SQLExecute('SELECT id FROM CurrancyEx WHERE (date = ' + sDate + ') AND (id_Currancy = ' +  ValuteID + ');');
               if svalute = '' then  SQLExecute ('INSERT INTO CurrancyEx (date, id_Currancy, sum) VALUES ('+ sDate +','+ ValuteID +','+arrStr[2] +');');
               if svalute <> '' then  SQLExecute ('UPDATE CurrancyEx SET sum = ' + arrStr[2] + ' WHERE id = ' + svalute);

           
код не тестировал )

Dmitry.

Re: [Решено] импорт данных из excel в базу данных

DriveSoft, работает и Ваш способ. Превосходно. мне все больше нравится Ваша программа.
Thanks a lot!

Re: [Решено] импорт данных из excel в базу данных

Вопрос. А если в файле появляется новая валюта, кода которой еще не было в базе. Как тогда добавить эту строку со связными полями ?

Re: [Решено] импорт данных из excel в базу данных

abgroup-artur wrote:

Вопрос. А если в файле появляется новая валюта, кода которой еще не было в базе. Как тогда добавить эту строку со связными полями ?

Посмотрите пожалуйста данный пример, в нем есть проверка, если района еще не было в базе но есть в CSV файле, то он автоматически создается
http://myvisualdatabase.com/forum/misc. … download=1


               //2 id_raion
               if arrStr[2] <> '' then
               begin
                    sid_raion := SQLExecute ('SELECT id FROM raion WHERE raion LIKE "' + arrStr[2] +'"');
                    if sid_raion = '' then
                    begin
                         SQLExecute ('INSERT INTO raion (raion) VALUES ("'+ arrStr[2] +'");');
                         sid_raion := IntToStr(Last_Insert_id('raion'));
                         if sid_raion = '-1' then sid_raion := 'NULL';
                    end;
               end else sid_raion := 'NULL';
Dmitry.

Re: [Решено] импорт данных из excel в базу данных

Спасибо за ответ, но я немного по другому реализовал. Готов выслушать конструктивную критику.

buttonSelected := MessageDlg ('Регион ' + arrStr[2] + ' отсутствует в базе. Добавить ?', mtWarning, mbYes + mbNo, 0);
                                               if  buttonSelected = 6 then  begin
                                               // Вносим изменения
                                               SQLExecute ('INSERT INTO zakazRegion (region) VALUES ("'+ arrStr[2] +'");');
                                               rID := SQLExecute ('SELECT id FROM zakazRegion WHERE region LIKE "' + arrStr[2] +'"');
                                               SQLExecute ('UPDATE zakaz SET id_zakazRegion = "' + rID + '" WHERE id = ' + s)
                                                                            end;

Re: [Решено] импорт данных из excel в базу данных

abgroup-artur
Можно и так )

Dmitry.