Импортируйте строки из файла с разделителями (.cvs) в таблицу MS-Access

#csv #ms-access #vba #ado

#csv #ms-access #vba #ado

Вопрос:

Справочная информация о системе: я работаю в Access 2010 с пользовательским интерфейсом и серверной частью Microsoft SQL Server 2008, где хранится база данных.

Справочная информация о проблеме: машина в моей лаборатории выдает результаты в виде файлов .csv. Эти файлы помещаются в папку на сервере. В настоящее время результаты вводятся в базу данных вручную. Цель состоит в том, чтобы иметь программу в access (VBA), которая считывает данные в файлах строка за строкой и вставляет каждую строку файла в определенную таблицу в базе данных. Мне было поручено использовать объекты ADO для достижения этой цели.

Прогресс: Моя проблема заключается в попытке чтения в каждой строке файла с разделителями. Мне дали справочный веб-сайт http://msdn.microsoft.com/en-us/library/ms974559.aspx но когда я попытался реализовать пример под заголовком, как мне использовать ADO для запроса текстового файла?и я получаю довольно много ошибок, настаивающих на том, что методы не были найдены специально при connection.Open. Я хочу получить значения в каждой строке и сохранить их во временных переменных для передачи в хранимую процедуру. хранимая процедура уже создана, и процесс для вставки новой записи уже создан.

Примечание к коду: код представляет собой функцию более низкого уровня, что означает, что он не считывает все файлы .csv в папке одновременно. Функции присваивается имя файла функцией более высокого уровня, и из этого имени файла функция будет считывать каждую строку из указанного файла и сохранять ее в таблице «tblICPMS». Вот пример того, как выглядит файл .cvs при открытии в Excel введите описание изображения здесь

Вот мой код:

 Public Function ImportICPMS(ThisFileName As String, ThisQueueID As Long, BatchID
As Long, InstrumentName As String, TechId As Long)
On Error GoTo HandleError

Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adCmdText = amp;H0001

Dim obj_fso As Object
Dim objconnection As connection
Dim objRecordset As Recordset
Dim strpathtotextfile As String

'test if file exists (newpath is a public path to folder)'
Set obj_fso = CreateObject("Scripting.FileSystemObject")
If obj_fso.FileExists(NewPath amp; "" amp; ThisFileName) Then
Else
    Err.Raise vbObjectError   1000, "MyProjectName.MyObjectName", "file " amp; ThisFileName amp; " for " amp; InstrumentName amp; " not found" 'if false error is raised
End If

Set objconnection = CreateObject("ADODB.connection") 'create ADO objects'
Set objRecordset = CreateObject("ADODB.recordset")

strpathtotextfile = NewPath amp; "" 'path to folder where file resides'

objconnection.Open "Provider=SQLOLEDB.1;Data Source=strpathtotextfile;Extended Properties=;HDR = YES;FMT = Delimited"

objrecordset.Open "SELECT * FROM " amp; ThisFileName,objconnection, adOpenStatic, adLockOptimistic, adCmdText

Do Until objRecordset.EOF

'I do not know what Wscript.Echo means but I want to save the acquired values into
 temp variables to pass them to a stored procedure that inserts them into the table'

Wscript.Echo objRecordset.Fields.Item("Sample Name")
Wscript.Echo objRecordset.Fields.Item("Date and Time Acquired")
Wscript.Echo objRecordset.Fields.Item("Element Full Name")
Wscript.Echo objRecordset.Fields.Item("Concentration")
Wscript.Echo objRecordset.Fields.Item("Units")

'code to insert rows into table would probably go here'
'code to clear out local objects would go here'

objRecordset.MoveNext

Loop
objRecordset.Close
objconnection.Close
 

Я не включил остальную часть кода или хранимую процедуру, но я могу, если кто-нибудь захочет их увидеть. Я хотел просто сосредоточить свой вставленный код на той части, над которой я работал.

Комментарии:

1. Также Const adCmdText = amp;H0001 продолжает автоматически меняться на Const adCmdText = amp;H1

Ответ №1:

Ваша проблема с несуществующими методами может заключаться в том, что он неправильно открывает CSV с помощью этого поставщика. Насколько мне известно, в SQLOLEDB.1 нет такой функции чтения текста.

Попробуйте это, измените:

 objconnection.Open "Provider=SQLOLEDB.1;Data Source=strpathtotextfile;Extended Properties=;HDR = YES;FMT = Delimited"
 

Для этого,

 objconnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=strpathtotextfile;Extended Properties=""Text;HDR=YES;FMT=Delimited"""
 

Обновление: замечена проблема с объявлениями:

 Dim objconnection As connection
Dim objRecordset As Recordset
 

Должно работать как,

 Dim objconnection As Object
Dim objRecordset As Object
 

Комментарии:

1. Спасибо за предложение, я переключил его и все равно получил ошибку компиляции «метод или элемент данных не найден» при подключении. открыть выделено

2. Я исправил свой ответ, поскольку заметил, что в расширенных свойствах нет текста, и обратите внимание на двойные кавычки

3. Все еще была проблема с objconnection. Open, вы знаете, является ли object.open методом, который можно использовать в VBA?

4. Да, ты можешь. Ссылка, которую вы используете, — это та, к которой я возвращался в течение многих лет. Какую последнюю ошибку вы получаете? ** Но я только что заметил проблему, в которой она объявлена, и обновит ответ. Моя теория заключается в том, что у него нет метода open, поскольку он использует соединение DAO (старше, чем ADO, и он открывается по-другому — меньше функциональности)

5. Эти эхо-сигналы предназначены для перехода в окно консоли из VBScript. В вашем случае измените wscript.echo на debug.print (их пример кода просто отображает значения для тестирования), и вам не понадобится . Свойство элемента. debug.print objRecordset.Fields("Sample Name").value

Ответ №2:

Эта процедура написана с использованием Delphi XE2, она считывает поля cvs и помещает их в таблицу ADO

 procedure addRowsFromCVS(cvsFileName : string; tblDocumentiRighe: TADOTable);

var
  cvsFileToImport   : TStringlist;
  rowCount          : integer;
  fieldCount        : integer;
  fields            : TStrings;
  fieldValues       : TStrings;

  start             : integer;
  currentFieldName  : string;
  currentFieldValue : string;

begin
  // create memory string list
  cvsFileToImport := TStringlist.create;
  fields          := TStringlist.create;
  fieldValues     := TStringlist.create;

  // load rows from file
  cvsFileToImport.loadFromFile(cvsFileName);

  // split fields row
  split(';', cvsFileToImport[0], fields);

  // first field
  start := 0;

  // for all the rows
  for rowCount := 1 to cvsFileToImport.count - 1 do begin
    // start insert
    tblDocumentiRighe.insert;

    // get field values
    split(';', cvsFileToImport[rowCount], fieldValues);

    // ...
    for fieldCount := start to fieldValues.count - 1 do begin
      currentFieldName  := fields     [fieldCount];
      currentFieldValue := fieldValues[fieldCount];

      if currentFieldValue <> '' then begin
        tblDocumentiRighe.fieldByName(currentFieldName).asString := currentFieldValue;
      end;
    end;

    // post record
    tblDocumentiRighe.post;
  end;

  // free
  fieldValues    .free;
  fields         .free;
  cvsFileToImport.free;
end;