2016-08-31 4 views
2

Моя цель - автоматизировать импорт CSV-файла в таблицу Access, сохраняя все данные в файле csv, в частности, за ведущие нули.Импорт CSV-файла в таблицу MSAccess без потери ведущих нулей

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

Вот соответствующий код для этого процесса, оставляя часть, в которой пользователь переходит в папку и выбирает CSV-файл.

Заметки о переменных:

FilePathAndName содержит полный путь и имя файла файла .csv

TableName содержит имя таблицы MSAccess я создаю

HeaderRow содержит первую строку csv-файла с именами столбцов. Имена столбцов никогда не будут содержать запятую.

ColumnNames() - это массив для хранения имен столбцов.

SQLStatement проведет SQL DDL заявление, чтобы создать таблицу

Open FilePathAndName For Input As #1 

' read first row to get column names because that will change every time 
Line Input #1, HeaderRow 
Close #1 
ColumnNames = Split(HeaderRow, ",") 

' create MSAccess table via DDL commands 
TableName = "GROUPS_TEST" 
SQLStatement = "CREATE TABLE " & TableName & "(" 
For i = 0 To UBound(ColumnNames) 
    SQLStatement = SQLStatement & "[" & ColumnNames(i) & "] text(255)" 
    If i < UBound(ColumnNames) Then 
     SQLStatement = SQLStatement & ", " 
    End If 
Next i 
SQLStatement = SQLStatement & ")" 
DoCmd.RunSQL SQLStatement 

' load .csv file into the table that was just created 
DoCmd.TransferText acImportDelim, , TableName, FilePathAndName, True 

Он работает безупречно вплоть до и включая заявление DoCmd.RunSQL, где создается таблица. Все столбцы определяются как текст (255), потому что есть некоторые столбцы, у которых есть ведущие нули, которые необходимо сохранить. Это не цифры; они являются буквенно-цифровыми значениями. Тогда проблема начинается. Я выполняю действие TransferText, и данные импортируются в таблицу из CSV-файла. За исключением того, что он разделяет ведущие нули от значений, которые имеют их , хотя я определенно определил все столбцы как столбцы TEXT.

Я уже несколько часов работаю в Интернете, и ничего не получилось. У меня нет спецификации импорта/экспорта из-за динамического характера файлов .csv. И я не знаю, что это все равно.

Одна вещь, о которой упоминалось, это редактирование параметра реестра для текстовых файлов в MSAccess, но я не смог найти особенности. Я использую Access 2007. Еще одна идея, которая возникла, заключалась в использовании файла schema.ini, но опять же из-за динамической природы файлов csv я не знаю, будет ли это работать.

Любая помощь будет с благодарностью принята. Спасибо заранее.

+0

Являются ли ведущие ноль динамическими или длина поля фиксирована? Если исправлено, вы можете установить свойство форматирования столбцов, чтобы сохранить ведущие нули –

+2

, так как вы читаете файл, чтобы получить количество столбцов, что мешает вам прокручивать строку и вставлять все строки? Я знаю, что это не тот ответ, который вам нужен, а просто сказать. КСТАТИ. Если вы действительно хотите это исправить, добавьте пустую/тестовую строку поверх вашего .csv-файла, чтобы все кубы имели текстовые значения. он заставит доступ читать все столбцы в виде текста, в противном случае доступ преобразует столбцы при передаче, а ваш - один из его побочных эффектов. –

+0

@random_answer_guy - ведущие нули являются динамическими. – Carl

ответ

1

Вместо использования имен полей из файла импорта укажите все поля в таблице импорта F1, F2, F3 и т. Д. Установите для параметра HasFieldNames значение false. Тогда первая строка всегда будет текстовой. Вы можете удалить эту строку позже. Затем либо измените имена полей на то, что вы хотите, либо вставьте данные в другую таблицу. Я всегда использую этот метод в любом случае, так что я могу очистить данные импорта, прежде чем вставлять его в конечные таблицы назначения.

+0

Установить значение HasFieldNames в false. Got error "Инструкция INSERT INTO содержит следующее неизвестное имя поля: 'F1' и т. Д. И т. Д. – Carl

+0

И имена полей должны быть первой, потому что именно так я определяю имена столбцов для создания таблицы. – Carl

+0

Я отредактировал мой ответ. – AVG

0

Вот решение, которое сработало для меня; кредит Райану Гриффину за его ответ на аналогичный вопрос о переполнении стека.

Перефразирование требования:

1) импортировать файл CSV, в MSAccess

2) должны сохранять все ведущие нули в полях, которые имеют их

3) .csv файл является динамическим ; число столбцов может (и обычно делает) изменяются с каждым импорта

4) тип данных может быть текст для всех столбцов

5) длины данных для данного столбца никогда не будет> 255

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

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

Вот пример файла .csv:

Имя, Департамент, расширение

"ManyJohns, Джон", 02,0987

Джон Smallberries, "Приобретения", "32939"

"Джон Bigbootie", 0001, GIGO


настройка системы: Windows 7 и M SAccess 2007

Я знал о настройке реестра, который помогал подобному проекту несколько лет назад. Win7 путь HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft \ Jet \ 4.0 \ Engines \ Text

Изменить значение ImportMixedTypes из большинства Тип до Текст

Первая попытка: с помощью действия TransferText

Переменные: TableName и FilePathAndName

DoCmd.TransferText acImportDelim,, TableName, FilePathAndName, True

Обратите внимание, что спецификация импорта отсутствует, поскольку упомянутое выше оно может меняться каждый раз. Результат: Заниженная ведущие нули и удалены текстовые значения

enter image description here


Вторая попытка: открытие.CSV-файл в качестве объекта доступа

Переменные: TableName, FilePath и FileName

SQLStatement = "INSERT INTO " & TableName & " SELECT * FROM [TEXT;FMT=Delimited;HDR=YES;IMEX=1;CharacterSet=437;DATABASE=" & FilePath & "].[" & FileName & "]" 
DoCmd.RunSQL SQLStatement 

Результат: Я никогда не видел раньше это раньше; вроде круто, подумал я. Но он также опустил ведущие нули и удалил текстовые значения.

enter image description here


Третья попытка: динамически создает спецификации импорта/экспорта Вот пост от Райана Гриффин, решение которой я приспособил для своих целей. Спасибо, сэр; Я приветствую вас.

Access Data Project Importing CSV File In VBA

И успех.

enter image description here

Из-за динамичного характера моих файлов .csv, вот окончательный код, основанный на работе Райана. Здесь я не включал объявления переменных; если меня интересуют, дайте мне знать, и я положу что-то еще немного более полированным.

Private Function CreateImportSpecification() 

    'based on solution from Ryan Griffin 21-JUN-2012 
    ImportSpecificationName = "ImportSpec_" & TableName 

    xml = "" 
    xml = xml & "<?xml version=""1.0"" encoding=""utf-8"" ?>" & vbCrLf 
    xml = xml & "<ImportExportSpecification Path=" & Chr(34) & FilePathAndName & Chr(34) & " xmlns=""urn:www.microsoft.com/office/access/imexspec"">" & vbCrLf 
    xml = xml & " <ImportText TextFormat=""Delimited"" FirstRowHasNames=""true"" FieldDelimiter="","" CodePage=""437"" Destination=" & Chr(34) & TableName & Chr(34) & " >" & vbCrLf 
    xml = xml & "  <DateFormat DateOrder=""MDY"" DateDelimiter=""/"" TimeDelimiter="":"" FourYearDates=""true"" DatesLeadingZeros=""false"" />" & vbCrLf 
    xml = xml & "  <NumberFormat DecimalSymbol=""."" />" & vbCrLf 
    xml = xml & "   <Columns PrimaryKey=""{none}"">" & vbCrLf 

    ' dynamically populate the 'FieldName' property of the <Column> attribute 
    For i = 0 To UBound(ColumnNames) 
     xml = xml & "   <Column Name=""Col" & (i + 1) & """ FieldName=""" & ColumnNames(i) & """ Indexed=""NO"" SkipColumn=""false"" DataType=""Text"" Width=""255"" />" & vbCrLf 
    Next i 

    xml = xml & "   </Columns>" & vbCrLf 
    xml = xml & " </ImportText>" & vbCrLf 
    xml = xml & "</ImportExportSpecification>" 

    ' if a specification already exists for this table, delete it 
    With CurrentProject.ImportExportSpecifications 
     For i = 0 To .Count - 1 
      If .Item(i).Name = ImportSpecificationName Then 
       .Item(i).Delete 
       Exit For 
      End If 
     Next i 
     ' add the specification to the database 
     .Add ImportSpecificationName, xml 
     ' could execute ImportSpecificationName right here 
     ' but would need to loop through the ImportExportSpecifications again 
     ' to make sure you had the right one 
    End With 

    DoCmd.RunSavedImportExport ImportSpecificationName 

End Function 

Единственное, что я могу понять, что MSAccess игнорирует ключ реестра (или я модифицирования неправильный) при импорте файла в формате CSV. В конечном счете, единственное, что сработало для меня, - это динамическое создание спецификации импорта/экспорта. Любой дополнительный вход приветствуется.

Смежные вопросы