Ongelmani on se, että ohjelmani hävittää käynnistyksessä vähän väliä oletusasetukset. Kun pitäisi sijoittaa tekstikenttään esimerkiksi lämpötilaksi 22, silloin tällöin siihen ilmaantuu tyyliin "102011356". Eräät kolme single-muuttujaa latautuvat usein nollina. Missä on vika?
Olen tallentanut kaiken "tiedot"-nimiseen luokkaan esim. näin:
'OK-nappia painettaessa tiedot.Aikavali = Int(aikatext.text) Call AloitusForm.TallenaTiedostoon
Ohjelman käynnistyessä tekstikentät täytetään vastaavalla tavalla, esim. aikatext.text = tiedot.Aikavali. Tiedot tallennetaan seuraavanlaiseen luokkaan, joka on globaalisti käytettävissä moduulissa:
Type Tallennustiedot
Aikavali as Integer
Raakadata(27,27,5) As Double
Temp As Single
Raja1 As Single
Raja2 As Single
'jne.
End Type
Public tiedot As TallennustiedotOletusasetukset haetaan binääritiedostosta alustukset.dat seuraavalla koodilla:
Public Sub HaeTiedotTiedostosta() Dim nAvaus As Integer nAvaus = FreeFile 'avataan Open App.path & "\alustukset.dat" For Binary As #nAvaus 'sama luokka "tiedot" sisältää kaiken datan Get #nAvaus, , tiedot Close #nAvaus End sub
Tallennus taas menee vastaavasti:
Public Sub TallennaTiedostoon() Dim nAvaus As Integer nAvaus = FreeFile 'avataan Open App.path & "\alustukset.dat" For Binary As #nAvaus 'sama luokka "tiedot" sisältää kaiken datan Put #nAvaus, , tiedot 'suljetaan Close #nAvaus End sub
Moi taas kisahalo!
Aluksi, olet pukannut kaman 'tiedot' nimiseen muuttujaan, joka on ilmentymä oliosta, jonka olet nimennyt nimellä 'Tallennustiedot'.
Nyt on niin, että kun pukkaat uutta kamaa binaaritiedostoon niin tiedostoa ei luoda enää uudestaan vaan se kirjoitetaan vanhan tiedon päälle alkaen tiedoston alusta jos kohdistinta ei erikseen siirretä osoittamaan esim. tiedoston loppua. Nyt jos dataputki on pidempi, kuin edellisellä kerralla, esim. joku luku on vaikkapa 1000 ja oli edellisellä tallennuskerralla 100 ja muu tallennettava tieto on pysyy ennallaan niin tiedoston pituus kasvaa hieman verrattuna edelliseen tallennuskertaan. Mutta jos jutska onkin toisin päin eli luku oli edellisellä kerralla 1000 ja nyt 100 niin tiedoston pituus ei lyhene.
Tämä on helppo ratkaista siten , että tuhoaa vanhan tiedoston ennen uuden tallentamista.
Toinen jutska joka auttaa on, että käyttää datan erotteluun jotain erotinmerkkiä/merkkijonoa jolloin se on kätevästi splitattavissa taulukkoon eikä 'kenttien' merkkimäärien muutoksilla ole enää mitään vaikutusta.
Lopuksi, jätä FreeFile-funktion käyttö ja käytä määrittelyyn yksinkertaista: As #1 määrittelyä...
Kiitos vastauksesta, Nea. Miten minun pitäisi tuo tallennus tehdä, jotta se tuhoaisi edellisen tiedon (vaikka tiedostonkin) kokonaan ja kirjoittaisi uuden? Olisiko jokin muu tallennusmuoto parempi? Pahoitteluni että olen nyyppä tässä.
Minulle on joka tapauksessa tärkeintä, että voin tallettaa tiedot tuollaisena oliona, ettei tarvitsisi 3-ulotteisten matriisien dataa parsea tekstitiedostosta.
Toiseksi tuo FreeFile tuli käyttöön siksi, että ohjelma valitti toistuvasti, että käytetty numero on käytössä, vaikka mielestäni olin sulkenut sen. Onko FreeFilessa jotain pahaa? Ajattelin, että se kävisi hyvin kun kerran tiedosto avataan ja suljetaan samassa aliohjelmassa.
Moi taas kisahalo!
esim näin...
Private Type AsetusTiedot
asetus() As Variant
End Type
Private asetukset As AsetusTiedot
Private Sub Form_Load()
If Dir("C:\polku\asetukset.dat") <> "" Then
Dim fileContent As Variant, i As Integer
Dim fileData() As String
Open "C:\polku\asetukset.dat" For Binary Access Read As #1
Get #1, , fileContent: Close #1
fileData = Split(fileContent, "|"): Close #1
Redim asetukset.asetus(UBound(fileData))
For i = 0 To UBound(fileData)
asetukset.asetus(i) = fileData(i)
End Select
Next i
End If
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
If Dir("C:\polku\asetukset.dat") <> "" Then
Kill("C:\polku\asetukset.dat")
End If
Dim fileData As Variant, i As Integer
For i = 0 To UBound(asetukset.asetus)
fileData = fileData & asetukset.asetus(i)
If i < UBound(asetukset.asetus) Then
fileData = fileData & "|"
End If
Next i
Open "C:\polku\asetukset.dat" For Binary Access Write As #1
Put #1, , fileData: Close #1
End SubMoi taas kisahalo!
tutki myös oheista esimerkkiä...
Private Type AsetusTiedot
asetus As Variant
End Type
Private asetukset(2) As AsetusTiedot
Private kokoPolku As String
Private table(1, 1, 1)
Private Sub Form_Load()
kokoPolku = Environ("userprofile") & "\Työpöytä\asetukset.dat"
If Dir(kokoPolku) <> "" Then
Open kokoPolku For Binary Access Read As #1
Get #1, , asetukset: Close #1
MsgBox asetukset(0).asetus(1, 0, 0)
MsgBox asetukset(1).asetus
MsgBox asetukset(2).asetus
End If
table(0, 0, 0) = 1
table(0, 0, 1) = 2
table(0, 1, 0) = 3
table(0, 1, 1) = 4
table(1, 0, 0) = 5
table(1, 0, 1) = 6
table(1, 1, 0) = 7
table(1, 1, 1) = 8
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
If Dir(kokoPolku) <> "" Then
Kill kokoPolku
End If
asetukset(0).asetus = table
asetukset(1).asetus = 1000000000#
asetukset(2).asetus = 100.01!
Open kokoPolku For Binary Access Write As #1
Put #1, , asetukset: Close #1
End SubTerve taas Nea. Katsotaan ymmärsinkö oikein jälkimmäisen esimerkin:
Ilmeisesti teet luokan, jonka ominaisuuksiin voi lisätä mitä vain. Sitten teet taulukkotyyppisen muuttujan juuri luodusta luokasta, ja lisäät muuttujaan uusia ominaisuuksia taulukon soluina. Mutta onko tuossa jokin etu siihen nähden, että lisäisi vain ominaisuuksia itse luokkaan?
Edellistä esimerkkiä en oikein ymmärrä. Onko kyseessä juuri jonkinlainen tekstin parseminen? Ilmeisesti talletat tiedot pitkänä merkkijonona, jossa erottimena on "|" ja sitten luet ne avattaessa samalla tavalla. En oikein näe, mitä matriisit tykkää tuollaisesta. :)
Kokeilin jälkimmäistä, se ei toimi. Ongelma on tuossa matriisien siirtelyssä, tulee vain "can't assign to array". Pitää kokeilla seuraavaksi edellistä esimerkkiä.
Äh, ongelma muuntui nyt täysin toiseksi:
Jälkimmäinen esimerkkisi näyttää toimivalta, mutta ongelmia tulee Variant-muuttujan kanssa. Logiikkani on seuraava: yritän säilyttää määrittelemäni Tiedot-olion ennallaan siksi, että dataa on niin paljon, että sen säilöminen pelkkiin asetukset()-taulukon indekseihin aiheuttaisi harmaita hiuksia. Siksi ajattelin käyttää asetukset()-taulukkoa tallennukseen ja siirtää dataa Tiedot-olion ja sen välillä. Esimerkki:
Public Sub Tallennatiedostoon() '(tiedoston avaaminen jne.) 'sijoitetaan taulukko asetukset(0).asetus = Tiedot.Isodoosiarvot 'sijoitetaan integer asetukset(1).asetus = Tiedot.Raja1 'jne End Sub Public Sub HaeTiedotTiedostosta() '(tiedoston avaaminen jne.) Tiedot.Isodoosiarvot = asetukset(0).asetus End Sub
Nyt ongelmaksi tulee se, että Tiedot.Isodoosiarvot on Double, eli sijoitus ei onnistu. Pitäisi ilmeisesti sijoittaa yksi kerrallaan kaikki arvot tai muuttaa Isodoosiarvot Variant-tyypiksi. Kun yritän muuttaa Variantiksi, kääntäjä valittaa, että moduuliin määritellyn olion koko on yli 64K. :/
Kysymys kuuluu: onko tähän olemassa jonkinlaista fiksua ratkaisua, vai pitääkö minun vaihtoehtoisesti A) siirrellä matriisitiedot yksi kerrallaan tai B) vain hyväksyä tuo asetukset()-taulukon indekseihin tallettaminen?
Moi taas kisahalo!
kisahalo kirjoitti:
...Ilmeisesti teet luokan, jonka ominaisuuksiin voi lisätä mitä vain...
En oikein käsitä tarvettasi inttää jostain luokan luomisesta, kun sellaista ei missään vaiheessa luoda. Type-määritteellä alustetaan olio, joka voi sisältää vain muuttujia tai toisia olioita (jotka voivat sisältää vain muuttujia tai jne.). Luokka taas voi sisältää mm. aliohjelmia (sub programs), funktioita (functions), ominaisuuksia (properties), ja esim em. oliorakenteita (structures) jne.
Ja jotta kaikki menisi vieläkin epäselvemmäksi niin...olion jäsenen arvoiksi voidaan sijoittaa objektiviittaus luokkaan. Mikäli sijoitat objektiviittauksen olioon niin VB6 ei suostu tallentaamaan oliotasi binaaritiedostoon.
mutta kaikessa yksinkertaisuudessaan jutska menee näin...
'Module1 Private Type AsetusTiedot taulu(10, 10, 5) As Double 'esim. int1 As Integer 'esim. sng1 As Single 'esim. 'jne. End Type Public asetukset As AsetusTiedot
'Form1
Private tiedostopolku As String
Private Sub Form_Load()
'Ladattaessa ohjelman päälomaketta:
'asetetaan merkkijonomuuttujan arvoksi tiedostopolku
tiedostopolku = "c:\asetukset.dat"
'tutkitaan ehtolauserakenteessa lytykö määritetyn
'tiedostopolun takaa määritetty tiedosto...
If Dir(tiedostopolku) <> "" Then
'ja jos löytyy niin avataan ko. tiedosto
'lukuoikeuksin, luetaan tiedoston data
'oliomuuttujan arvo(i)ksi ja suljetaan tiedosto.
Open tiedostopolku For Binary Access Read As #1
Get #1, , asetukset: Close #1
'tähän koodia jolla haet arvoja oliomuuttujasta
'ja sijoittelet haluamiesi muuttujien arvoiksi...
End If
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
'Ohjelman päälomaketta suljettaessa:
'jos määritetyn tiedostopolun päästä
'löytyy polussa määritetty tiedosto niin...
If Dir(tiedostopolku) <> "" Then
'tapetaan ko. tiedosto!
Kill tiedostopolku
End If
'luodaan uusi binaaritiedosto merkkijonomuuttujassa
'tiedostopolku' määritettyyn hakemistoon samaisessa
'muuttujassa määritetyllä tiedostonimellä...
Open tiedostopolku For Binary Access Write As #1
'ja kirjoitetaan 'tämänhetkiset' asetukset
'nyt luotuun tiedostoon ja suljetaan tiedosto.
Put #1, , asetukset: Close #1
End Sub"vähän lisävalaistusta..?"
Private Type OlioTyyppi
kama As Variant
nimi As String
End Type
Private oliot() As OlioTyyppi
Private arvotosi As Boolean
Private luotu As Boolean
Private Sub Command1_Click()
If arvotosi Then Exit Sub
Dim Bytes() As Byte
Open "c:\windows\system32\notepad.exe" _
For Binary Access Read As #1
Get #1, , Bytes: Close #1
Dim ub As Integer
On Error Resume Next
ub = UBound(oliot)
If Err <> 0 Then
Err.Clear
On Error GoTo o
ReDim oliot(0)
Else
ReDim Preserve oliot(UBound(oliot) + 1)
End If
oliot(UBound(oliot)).kama = Bytes: Erase Bytes
oliot(UBound(oliot)).nimi = "notepad.exe"
arvotosi = True
End Sub
Private Sub Command2_Click()
If Not arvotosi or luotu Then Exit Sub
Dim laskuriarvo As integer
For laskuriarvo = LBound(oliot) To UBound(oliot)
If oliot(laskuriarvo).nimi = "notepad.exe" Then
Open App.Path & "\" & oliot(laskuriarvo).nimi _
For Binary Access Write As #1
Put #1, , oliot(laskuriarvo).kama: Close #1
Do While Dir(App.Path & "\" & _
oliot(laskuriarvo).nimi)) = "": DoEvents: Loop
Shell App.Path & "\" & oliot(laskuriarvo).nimi
luotu = True: Exit Sub
End If
Next
End SubOlen pahoillani terminologian epätarkkuudesta, kyseessä on vain se, että käytin väärää sanaa. Kiitos kärsivällisyydestä tällaisen aloittelijan kanssa. :)
Kokeilen näitä tänään ja palaan asiaan.
Aihe on jo aika vanha, joten et voi enää vastata siihen.