Avatar billede gylling Juniormester
04. april 2013 - 20:27 Der er 14 kommentarer og
1 løsning

Importe fra json db til access db

Jeg har fået en tekst fil som eksport fra en json db.

ekspl.

{ "results": [
{
  "stedNr": 1.0,
  "nr": 1.0,
  "Underemne": "renlighed",
  "type": 1.0,
  "sprgsml": "Borde er rene og pæne",
  "point": 10.0,
  "sekundrType": null,
  "evtSekundrSprgsml": null,
  "createdAt": "2013-04-03T18:25:54.796Z",
  "updatedAt": "2013-04-03T18:25:54.796Z",
  "objectId": "rvuwIGtoOD"
}
] }

Det skulle gerne indlæses som en linje.

Nogen der har en ide?
Avatar billede Slettet bruger
05. april 2013 - 00:23 #1
Der er mange søgeresultater på 'json to csv'
Det afhænger af opgavens skala og anvendelsesområde hvordan det løses - havde det alene været ovennævnte stump, kunne den blot underkastes f.eks lidt søg og erstat og smides i en kodestump:

Sub fracment()
    Dim arr, i, sql, types, unemb
    arr = Array( _
        "stedNr", 1#, _
        "nr", 1#, _
        "Underemne", "renlighed", _
        "type", 1#, _
        "sprgsml", "Borde er rene og pæne", _
        "point", 10#, _
        "sekundrType", Null, _
        "evtSekundrSprgsml", Null, _
        "createdAt", "2013-04-03T18:25:54.796Z", _
        "updatedAt", "2013-04-03T18:25:54.796Z", _
        "objectId", "rvuwIGtoOD")
    types = Array("single", "single", "text", "single", "text", "single", "integer", "text", "date", "date", "text")
    For i = 1 To 11
        sql = sql & arr(2 * i - 2) & " " & types(i - 1) & ",": Next
    CurrentDb.Execute "create table unknownExam (" & sql & "CONSTRAINT objectId_PK PRIMARY KEY(objectId))"
    sql = ""
    For i = 1 To 11
        unemb = arr(2 * i - 1)
        If IsNull(unemb) Then
            unemb = "null"
        Else
            If types(i - 1) = "date" Then
                unemb = "#" & Replace(Split(unemb, ".")(0), "T", " ") & "#"
            ElseIf types(i - 1) = "text" Then
                unemb = """" & unemb & """"
            End If: End If
        sql = sql & unemb & ",": Next
    CurrentDb.Execute "insert into unknownExam values(" & Left(sql, Len(sql) - 1) & ")"
End Sub

Men som nævnt: fortæl hvordan det skal anvendes hvis du vil have en realistisk løsning.
Avatar billede gylling Juniormester
05. april 2013 - 08:06 #2
Hej

Det skal bruges til at indlæse i en tabel.

Det er et spørgeskema hvor der er rigtigt mange sprøgsmål.
>200 og er en .txt fil

Den stump var bare et eksempel på et spørgsmål.

Tabel ind holde følgende felter:

Salgsted_Id,Spørgsmål_1,AntalPoint;SpørgsMål_2,SvarDato

Salgssted_Id; "stedNr": 1.0,
SpørgsMål_1 "nr": 1.0,
Springover "Underemne": "renlighed",
Sprngover "type": 1.0,
Springover "sprgsml": "Borde er rene og pæne",
AntalPoint; "point": 10.0,
Springover "sekundrType": null,
SpørgsMål_2; "evtSekundrSprgsml": null,
SvarDato; "createdAt": "2013-04-03T18:25:54.796Z",
Springover "updatedAt": "2013-04-03T18:25:54.796Z",
springover "objectId": "rvuwIGtoOD"

Håber det hjalp
Avatar billede Slettet bruger
06. april 2013 - 11:39 #3
Ja - det giver god mening med feltvalgsbegrænsning og -navngivning

En ting til:

Gider du liste din 200 posters fil her - dog klippet ned til 2 poster - men sådan at den indledene/afsluttende omklamring af {[ tegn og 'postseparering' passer.

Det er faktisk meget interessant med json - der er masser info på json.org - vb og asp stuff
Avatar billede gylling Juniormester
06. april 2013 - 23:33 #4
{ "results": [
{
  "stedNr": 1.0,
  "nr": 1.0,
  "Underemne": "renlighed",
  "type": 1.0,
  "sprgsml": "Borde er rene og pæne",
  "point": 10.0,
  "sekundrType": null,
  "evtSekundrSprgsml": null,
  "createdAt": "2013-04-03T18:25:54.796Z",
  "updatedAt": "2013-04-03T18:25:54.796Z",
  "objectId": "rvuwIGtoOD"
},
{
  "Underemne": "Kvalitet",
  "evtSekundrSprgsml": "(evt. kr)",
  "nr": 3.0,
  "point": 0,
  "sekundrType": 3.0,
  "sprgsml": "hvad blev der købt",
  "stedNr": 1.0,
  "type": 3.0,
  "createdAt": "2013-04-03T18:25:55.157Z",
  "updatedAt": "2013-04-03T18:27:18.448Z",
  "objectId": "xlrvBMNNJv"
}
] }
Avatar billede Slettet bruger
08. april 2013 - 14:30 #5
Var en smule omstændigt, og jeg gad ikke lave generelt json parsning.

Er afhængigt af referencer til 'Microsoft scripting runtime' (menulinie->tool->references)

jsonArr2tbl anvendes sådan

Sub viserAnvendelse()
   
        jsonArr2tbl "D:\home\dev\devel\access\jsonrecs.txt", _
        Array( _
            Array("stedNr", jFldtypes.jSingle), _
            Array("nr", jFldtypes.jSingle), _
            Array("point", jFldtypes.jSingle), _
            Array("evtSekundrSprgsml", jFldtypes.jtext), _
            Array("createdAt", jFldtypes.jdate)), _
        "insert into tabel1(stedNr,nr,point,evtSekundrSprgsml,createdAt) values("
End Sub

Tabellen 'tabel1' skal eksistere i forvejen. De filtype enums der er parametre muliggør at tilpasse i jsonArr2tbl i select case, så de passer til formålet - bemærk at createdAt er af type dato/klokkeslet.

og her er et dump af modulet

Option Compare Database
Option Explicit
Enum jFldtypes
    jtext = 2
    jSingle = 3
    jdate
End Enum

Function FileSystemObject(): Set FileSystemObject = New FileSystemObject: End Function


Sub jsonArr2tbl(fileN, fldSpecArray, sqlInsertPreStr)
    Dim rec, fldPair, fldArr, fldSpec, fldDict As Dictionary, sql
    For Each rec In Split(Replace(Replace(Replace(Replace(Replace(Replace( _
        FileSystemObject().OpenTextFile(fileN, 1, 0).ReadAll, _
        " ", ""), vbCr, ""), vbLf, ""), vbTab, ""), "{""results"":[{", ""), "}]}", ""), "},{")
        Set fldDict = New Dictionary
        sql = ""
        For Each fldPair In splitWOdelimInEmbedStr(rec)
            fldArr = splitWOdelimInEmbedStr(fldPair, ":")
            fldDict.Add fldArr(0), fldArr(1): Next
        For Each fldSpec In fldSpecArray
            Select Case fldSpec(1)
                Case jFldtypes.jSingle, jFldtypes.jtext
                    sql = sql & fldDict("""" & fldSpec(0) & """") & ","
                Case jFldtypes.jdate
                    sql = sql & "#" & Replace( _
                        Replace(Split(fldDict("""" & fldSpec(0) & """"), ".")(0), "T", " "), """", "") & "#,"
                End Select
        Next
        CurrentDb.Execute sqlInsertPreStr & Left(sql, Len(sql) - 1) & ")"
    Next
   
End Sub

Function splitWOdelimInEmbedStr(str, Optional delim = ",", Optional embedChar = """")
    Dim i%, isInStr%, strlen, ch, delimItem
    Const delimReplacement = "\delim\"
    strlen = Len(str)
    Do
        i = i + 1
        ch = Mid(str, i, 1)
        If ch = embedChar Then
            isInStr = Not isInStr
        ElseIf isInStr And ch = delim Then
                str = Left(str, i - 1) & delimReplacement & Right(str, strlen - i)
                strlen = strlen + 6
                i = i + 6
        End If: Loop Until i >= strlen
       
        For Each delimItem In Split(str, delim)
            add2list splitWOdelimInEmbedStr, Replace(delimItem, delimReplacement, delim): Next
End Function


Sub add2list(V, i)
    On Error Resume Next
    ReDim Preserve V(UBound(V) + 1)
    If err.Number = 13 Then ReDim V(0)
    If IsObject(i) Then Set V(UBound(V)) = i Else V(UBound(V)) = i
End Sub
Avatar billede Slettet bruger
08. april 2013 - 15:00 #6
ser lige en SPOT violation, der lægges 6 skulle have været len(delimReplacement)-1.
Avatar billede gylling Juniormester
09. april 2013 - 19:19 #7
Hej

Har oprette en marco der kalder function "splitWOdelimInEmbedStr"


Få fejlen.

The expression yiu entered has a function containing the wrong number ao arguments"
Avatar billede Slettet bruger
09. april 2013 - 19:47 #8
Hvorfor har du oprettet en makro?

Fejlbeskeden beskriver retvisende netop de detaljer der ikke giver nogen mening.

splitWOdelimInEmbedStr er fra min side, i denne sammenhæng, lavet til at blive kaldt fra jsonArr2tbl(...)

Men den (splitWOdelimInEmbedStr) er skrevet meget generelt - så forstår man argument/returværdi kan den anvendes hvor man har brug for det - WO står for Without - det er en 'specieludgave' af split
og returnere som denne et array

Jeg kan ikke lige se, hvad du skal med makro - men det er sådan er der så meget - det er i hvert fald prisværdigt at prøve sig frem.

Jeg uploader lige en mdb - du skal nok konvertere da jeg anvender access 2000 - vender lige tilbage om et par timers tid.
Avatar billede gylling Juniormester
09. april 2013 - 21:12 #10
Hej

Det virker hvis jeg bruger den fik som du har medsent.

Hvis jeg bruger min egen få jeg denne fejl.

Der er en syntaksfejl i INSERT INTO-sætningen.

CurrentDb.Execute sqlInsertPreStr & Left(sql, Len(sql) - 1) & ")"
Avatar billede Slettet bruger
09. april 2013 - 22:01 #11
Det er de situationer hvor man lærer debugning - sæt et breakpoint og overvej hvad der ser forkert ud efter udførelsen af følgende i immediate vinduet:
?sqlInsertPreStr & Left(sql, Len(sql) - 1) & ")"

Man kan oprette en forespørsel med udtrykket - det giver nogle gange mere detaljeret fejlmeddelelse.

Du har vel ikke kopiret kaldet i 'Sub viserAnvendelse()...' uden at chekke at felternes type (jFldtypes.jSingle mm.) passer med din tabel.

Min løsning er heller ikke færdig, da jeg ikke kender dit behov fuldt ud - bemærk parsning af jFldtypes.date i 'select case' delen i  jsonArr2tbl
Avatar billede gylling Juniormester
09. april 2013 - 22:07 #12
behovet er kun at kunne indlæse en fil fr json

kan jeg sende dig en kopi af filen?
Avatar billede gylling Juniormester
09. april 2013 - 22:08 #13
Brugt din db
Avatar billede gylling Juniormester
12. april 2013 - 10:17 #14
Hej

Nu virker det.

Har så en anden fil der skulle indlæse. Prøve at rette i din kode med det gik ikke.

kopi af filen:

https://docs.google.com/file/d/0B-iFAYdhi2WGWEV4eFQ0WHhpQlU/edit?usp=sharing

Kan du hjælpe.

Ellers virke det perfekt
Avatar billede gylling Juniormester
15. april 2013 - 09:58 #15
Hej

Det virke fint.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Dyk ned i databasernes verden på et af vores praksisnære Access-kurser

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester