2013-11-27 3 views
1

Я импортирую sql в базу данных Access и работаю над разбором данных в правильные таблицы и поля. Снова я обращаюсь к вам, гуру, чтобы помочь в решении проблемы.Разбор строк в Access

Одно из импортируемых полей имеет разделенные запятыми значения, которые необходимо разделить. В строке может быть от одного до десяти возможных значений.

PHO,Rosgen,NRCS,EMAP,T-DL,YSI-DL 

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

SELECT Left([FieldForms],InStr([FieldForms],",")-1) AS DEQ_SampleTypeID 
FROM tblSiteVisit 
UNION ALL 
SELECT Mid([FieldForms],InStr([FieldForms],",")+1,4) AS DEQ_SampleTypeID 
FROM tblSiteVisit 
UNION ALL 
SELECT Mid([FieldForms], 11, 4) AS DEQ_SampleTypeID 
FROM tblSiteVisit 
UNION ALL 
SELECT Mid([FieldForms], 16, 4) AS DEQ_SampleTypeID 
FROM tblSiteVisit 
UNION ALL 
SELECT Mid([FieldForms], 21, 4) AS DEQ_SampleTypeID 
FROM tblSiteVisit 
UNION ALL 
SELECT Mid([FieldForms],InStrRev([FieldForms],",")-4,4) AS DEQ_SampleTypeID 
FROM tblSiteVisit 
UNION ALL 
SELECT Right([FieldForms],InStr([FieldForms],",")-1) AS DEQ_SampleTypeID 
FROM tblSiteVisit 

Если я использую InStrRev или правильную функцию я получаю повторы, если есть меньше, чем максимум также с помощью функции Mid результатов в пустых строках.

Есть ли способ, чтобы разобрать строку, как это и только получить результаты из строки

+0

Это будет проще ИМО с процедурой доступа VBA вместо запроса. Будет ли это подходящим вариантом для вас? – HansUp

+0

Все, что сработает, это вариант – pja

+0

'Split (FieldForms,", ")' даст вам строковый массив. Добавьте строку в таблицу назначения для каждого элемента массива. – HansUp

ответ

1

Put следующие функции в модуле:

Function CountCSWords (ByVal S) As Integer 
    ' Counts the words in a string that are separated by commas. 

    Dim WC As Integer, Pos As Integer 
    If VarType(S) <> 8 Or Len(S) = 0 Then 
     CountCSWords = 0 
     Exit Function 
    End If 
    WC = 1 
    Pos = InStr(S, ",") 
    Do While Pos > 0 
     WC = WC + 1 
     Pos = InStr(Pos + 1, S, ",") 
    Loop 
    CountCSWords = WC 
    End Function 

    Function GetCSWord (ByVal S, Indx As Integer) 
    ' Returns the nth word in a specific field. 

    Dim WC As Integer, Count As Integer, SPos As Integer, EPos As Integer 
    WC = CountCSWords(S) 
    If Indx < 1 Or Indx > WC Then 
     GetCSWord = Null 
     Exit Function 
    End If 
    Count = 1 
    SPos = 1 
    For Count = 2 To Indx 
     SPos = InStr(SPos, S, ",") + 1 
    Next Count 
    EPos = InStr(SPos, S, ",") - 1 
    If EPos <= 0 Then EPos = Len(S) 
    GetCSWord = Trim(Mid(S, SPos, EPos - SPos + 1)) 
    End Function 

Затем поместите поле в запросе, как это:

MyFirstField: GetCSWord([FieldForms],1) 

Поместите еще один в так:

MySecondField: GetCSWord([FieldForms],2) 

И т.д. ... за столько, сколько вам нужно.

+0

Мне кажется, что использование функции [Split()] (http://office.microsoft.com/en-ca/access-help/split-function-HA001228911.aspx) может значительно упростить этот код. –

+0

Не удалось выяснить, как это сделать в запросе. Split() создаст массив. Если вы можете понять это, опубликуйте его! –

+0

Не лучший мир в VBA ... Я создал модуль и запрос, но он не работает, я, кажется, что-то испортил. Я получаю сообщение об ошибке с недопустимыми скобками. Можете ли вы задать мне запрос в sql? – pja

1

Этот код VBA считывает текстовые значения из FieldForms в tblSiteVisit, разделяет этот текст на подстроки, а затем хранит каждый из подстрок в DEQ_SampleTypeID в новой строке добавляется к tblDestination.

Dim astrItems() As String 
Dim db As DAO.database 
Dim i As Long 
Dim qdf As DAO.QueryDef 
Dim rs As DAO.Recordset 
Dim strInsert As String 

strInsert = "INSERT INTO tblDestination (DEQ_SampleTypeID)" & vbCrLf & _ 
    "VALUES ([array_item]);" 

Set db = CurrentDb 
Set rs = db.OpenRecordset("tblSiteVisit", dbOpenTable, dbOpenSnapshot) 
Set qdf = db.CreateQueryDef(vbNullString, strInsert) 
Do While Not rs.EOF 
    astrItems = Split(rs!FieldForms, ",") 
    For i = 0 To UBound(astrItems) 
     qdf.Parameters("array_item") = astrItems(i) 
     qdf.Execute dbFailOnError 
    Next 
    rs.MoveNext 
Loop 
rs.Close 
Set rs = Nothing 
Set qdf = Nothing 
Set db = Nothing 
+0

Я на 99% уверен (всегда оставляю последнее 1% ...), что это просто вставляет новую запись в таблицу для каждого значения, разделенного запятой. Несмотря на то, что OP разместил строку UNION ALL SQL, в его тексте говорится, что он ищет способ получить каждый CSV, который говорит мне, что он хочет, чтобы они разделились на отдельные ** поля **.Это имеет смысл, чем создание новых ** записей ** для каждого значения. –

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