【问题标题】:Parsing string values in Access在 Access 中解析字符串值
【发布时间】:2015-06-01 11:04:41
【问题描述】:

我正在将 sql 导入到我的 Access 数据库中,并且正在将数据解析为正确的表和字段。我再次求助各位大师来帮助解决问题

其中一个导入的字段有逗号分隔的值需要分隔。字符串中有 1 到 10 个可能的值。

 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 或 Right 函数,我会得到重复,如果少于最大值,使用 Mid 函数也会导致空行。

有没有办法解析出这样的字符串,只从字符串中获取结果

【问题讨论】:

  • 使用 Access VBA 过程而不是查询会更容易 IMO。这对你来说是一个合适的选择吗?
  • 任何可行的方法都是一种选择
  • Split(FieldForms, ",") 会给你一个字符串数组。为数组中的每个项目在目标表中添加一行。

标签: sql ms-access


【解决方案1】:

将以下函数放入一个模块中:

   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)

等等...根据您的需要。

【讨论】:

  • 在我看来,使用Split() 函数可以大大简化这段代码。
  • 无法弄清楚如何在查询中执行此操作。 Split() 将创建一个数组。如果你能弄明白,贴出来吧!
  • VBA 不是世界上最好的...我创建了模块和查询,但它不起作用,我似乎在某个地方搞砸了。我收到有关无效括号的错误。可以给我sql里面的查询吗?
  • 试试这个:从 tblSiteVisit 中选择 GetCSWord([FieldForms],1) 作为 MyFirstField,GetCSWord([FieldForms],2) 作为 MySecondField。也就是说,假设逗号分隔值的字段名称是“FieldForms”。如果不是,请相应地更改 SQL 代码。这应该会给您一个包含字段中前 2 个值的查询。如果 ti 有效,请相应地重复。如果没有,请告诉我发生了什么。
【解决方案2】:

此 VBA 代码从 tblSiteVisit 中的 FieldForms 读取文本值,将该文本拆分为子字符串,然后将每个子字符串存储在 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

【讨论】:

  • 我有 99% 的把握(总是留下最后的 1%...)这只会为每个逗号分隔值在表中插入一条新记录。尽管 OP 发布了一个 UNION ALL SQL 字符串,但他的文字表明他正在寻找一种方法来分解每个 CSV,这告诉我他希望将它们分成单独的 字段。这比为每个值创建新的记录更有意义。
猜你喜欢
  • 2011-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-18
  • 2021-03-19
  • 1970-01-01
  • 2010-11-07
  • 1970-01-01
相关资源
最近更新 更多