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

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