Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB6: Muutos, ettei kaikki muut katoaisi?

Sivun loppuun

juku [25.02.2004 18:04:09]

#

Koodi toimii, kun muuttaa yhtä käyttäjää, niin samalla kaikki muut tiedostosta olevat tunnukset katoavat. Mitä pitäisi tehdä, jotta vain muutettava tietue muuttuisi ja muut pysyisi samana?

Option Explicit
  'Esittelyn jälkeen ObjFso voidaan panna viittaamaan
  'FileSystemObject- tyyppiä olevaan muutujaan.
  Dim ObjFso As scripting.FileSystemObject

  'Esitellään muuttuja ObjTextStream, joka on tyyppiä TextSream
   Dim ObjTextStream As scripting.TextStream
   'Esitellään objektimuuttuja ObjFso(=File system object)
   Dim rivi As String

Private Sub cmdSelaa_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

        Dim rivi As String
        Dim taulu() As String
        Dim tiedot As String
        Dim i As Integer

        'luetaan käyttäjätunnus ja salasana muuttujaan rivi
        rivi = "txtKäyttäjä;txtSalasana"

            For i = 0 To ObjTextStream.AtEndOfStream

                rivi = ObjTextStream.ReadLine
'Splip funktio jakaa merkkijonon taulukkoon ;- merkin kohdalta
                taulu = Split(rivi, ";")
                txtKäyttäjä = taulu(0)
                txtSalasana = taulu(1)
                i = i + 1
             Next
        'Jos kyseessä on viimeinen tietue, niin ohjelma lähettää
        'ilmoituksen siitä
            If ObjTextStream.AtEndOfStream Then
                MsgBox "Se oli viimeinen tietue. Sulje selain lomakkeen yläkulmasta"
            End If
End Sub

Private Sub cmdTalleta_Click()
  Dim strrivi As String
  Set ObjTextStream = ObjFso.OpenTextFile("C:\Testi\Tunnukset.txt", ForWriting)
   'Annetaan strRivi muuttujalle arvoksi merkkijono, joka saadaan
  'yhdistämällä käyttäjätunnus, ; ja salasana
   strrivi = txtKäyttäjä & ";" & txtSalasana

   ObjTextStream.WriteLine strrivi

   ObjTextStream.Close
   MsgBox "Muutos tallennettu tiedostoon. Sulje selain lomakkeen yläkulmasta"

End Sub


Private Sub Form_Load()
   Set ObjFso = CreateObject("scripting.FileSystemObject")
   Set ObjTextStream = ObjFso.OpenTextFile("C:\Testi\Tunnukset.txt", 1)

End Sub

sqwiik [25.02.2004 20:10:14]

#

Sikäli kun huomaan, niin luet tiedoston rivi kerrallaan, ja talletat vain muokatun rivin. Ota muokkauksen ajaksi kaikki käyttäjät ja salasanat muistiin taulukkoon/rakenteeseen, ja tallennuksessa sitten tallennat kaikki tunnukset & salasanat for/tms. silmukassa.

Vinkkejä - lue tiedoston kaikki rivit string()-taulukkoon, ja muokkaa siitä yhtä alkiota. Muut jäävät siis koskematta.

hunajavohveli [25.02.2004 20:24:21]

#

Tuo on varmaan parempi, mutta yksi keino on avata auki kaksi tiedostoa, joista tiedostoon 2 kopioidaan tiedosto 1. Sitten luetaan tiedostosta 1 yksi tieto, ja vaikka muut katoavat, niin kopioidaan ne takaisin tiedostosta 2. Tuota joutuu käyttämään, kun QB:ssä loppuu STRING-muisti, mutta VB:ssähän tämä on varmaan jotenkin korjattu...?

juku [26.02.2004 18:24:42]

#

En saanut onnistumaan sen kummemmin... Kerrotko vähän tarkemmin: miten muistiinotto ja tallennus tapahtuvat?

sqwiik [26.02.2004 18:56:26]

#

Noo... kaikkien on alkuun päästävä :)
En kertaa lataus/tms koodinpätkiä, vaan laitan tähän esimerkkiohjelman rakenteen.
Määritä aluksi

Dim tiedostonrivit() As String

Ja luet siihen tiedoston rivit eli

For i = 0 To ObjTextStream.AtEndOfStream
  tiedostonrivit(i) = ObjTextStream.ReadLine
Next

Nyt kaikki on tallessa. Muokattavaksi saat halutun tunnuksen & salasanan rivinumeron perusteella.

Dim taulu() As String
  taulu = Split(tiedostonrivit(i), ";")
  txtKäyttäjä = taulu(0)
  txtSalasana = taulu(1)

Vastaavasti, muokattu rivi laitetaan seuraavasti:

tiedostonrivit(i) = txtKäyttäjä & ";" & txtSalasana

Kun tallennetaan, niin kelataan kaikki rivit uudelleen.

i = 0 'laskuri alkuun
While tiedostonRivit(i) <> "" 'kirjoitetaan niin kauan kun tietoa riittää
  ObjTextStream.WriteLine tiedostonRivit(i)
  i = i + 1
Wend

Antti [27.02.2004 10:57:32]

#

Samassa kirjastossa, josta poimit FileSystemObject:in on myös Dictionary-objekti:

Dictionary objectilla voit luoda arvopareja (Key/Value) Laitat käyttäjänimen Key-ominaisuuteen ja Salasanan Key:n arvoksi.

Kun tarkistat arvoja voit tehdä sen:
if oDict.Exists("Käyttäjätunnus") then...

Eli koodin alkuun

Dim oDict As New Dictionary

Nyt voit käyttää oDict-objektia seuraavasti.

Arvojen lukeminen:

Do While Not ObjTextStream.AtEndOfStream
 tiedostonrivit = Split(ObjTextStream.ReadLine,";")
 oDict.Add tiedostonrivit(0),tiedostonrivit(1)
Loop

Tallentaminen:

For Each Key In oDict.Keys
    ObjTextStream.WriteLine Key & ";" & oDict(Key)
Next

Edit: Koodit koodeiksi...:)

juku [01.03.2004 16:22:45]

#

Auttakaan vielä... sqwiikin ehdotusta en saa toimivaksi (en osannut ilmeisesti määritellä tiedostonrivit() oikeaan paikkaa tai jotain muuta). Antin ehdostusta kokeilin, mutta ei tallenna mitään. Mulla on nyt tiedosto auki lukemista varten. Kun yritän muuttaa tiedostoa,niin että siihen voidaan kirjoittaa, ei se vaan onnistu. Missä kohdassa tiedosto avataan kirjoittamista varten?

setä [01.03.2004 17:59:39]

#

En ole tuota FSO:käyttänyt mutta siinä on varmaan sama juttu eli tekstitiedosto on ensin suljettava lukumoodista ja avatta sitten uudelleen kirjoitusmoodiin. Tiedostoon on kirjoitettava kaikki alusta muutoskohtaan, sen jälkeen muutettu rivi jonka jälkeen loput. tarvitset siis toisen tiedoston jonne kirjoitat ja toisen josta luet.

juku [01.03.2004 18:51:27]

#

Joo. Niin yritin, mutta tuntuu siltä, että se toimii mulla vain silloin, kun tiedosto avataan formin avaamisvaiheessa ja suljetaan, kun formi suljetaan... Jos yrittää siirtää niitä muualle toimiminen loppuu kokonaan. Onkohan niiden määrittelyissä jokin vika?

setä [01.03.2004 19:26:59]

#

Itse tekisin tuon niin, että lukisin tiedot hatiedostoon (Random). Sinne voi kirjoittaa ja lukea samalla avauksella ja muokkaus on todella helppoa. Mahtoiko vastaava topikki olla ennenkin kun tuntuu vanhan toistamiselta?

remontti-reiska [01.03.2004 19:50:25]

#

https://www.ohjelmointiputka.net/koodivinkit/24153-vb6-tietyn-rivin-haku-tiedostosta
Eikös tuossa olisi jotain ohjeita. Haet tuolla sen tietyn rivin ja teet sille mitä lystäät ja lisäät sen sitten rivinä sinne tekstiedostoon tai mihin hyvänsä.

Antti [01.03.2004 21:56:46]

#

Huoh... en jaksa... tein sen valmiiksi sinulle...
Tässä on koko luokka siitä mitä olet koodaamassa:

1. Lisää projektiisi luokka klikkaamalla Project->Add Class Module
2. Laita luokallesi nimeksi Password
3. Kopioi alla oleva koodi luokkaan

Option Explicit
Public oDict As New Dictionary
Private mvarDelimiter As String
Private mvarFilePath As String
Private mvarErrNumber As Long
Private mvarErrDescription As String
Private mvarErrSource As String
Public Property Let ErrSource(ByVal vData As String)
    mvarErrSource = vData
End Property

Public Property Get ErrSource() As String
    ErrSource = mvarErrSource
End Property

Public Property Let ErrDescription(ByVal vData As String)
    mvarErrDescription = vData
End Property

Public Property Get ErrDescription() As String
    ErrDescription = mvarErrDescription
End Property

Public Property Let ErrNumber(ByVal vData As Long)
    mvarErrNumber = vData
End Property

Public Property Get ErrNumber() As Long
    ErrNumber = mvarErrNumber
End Property

Public Property Let FilePath(ByVal vData As String)
    mvarFilePath = vData
End Property

Public Property Get FilePath() As String
    FilePath = mvarFilePath
End Property

Public Property Let Delimiter(ByVal vData As String)
    mvarDelimiter = vData
End Property

Public Property Get Delimiter() As String
    Delimiter = mvarDelimiter
End Property

Public Function ReadFile() As Boolean
    Dim objFile As New FileSystemObject
    Dim tsTextIn As TextStream
    Dim strFileData() As String
On Error GoTo errhandler
    If objFile.FileExists(FilePath) Then
        Set tsTextIn = objFile.OpenTextFile(mvarFilePath, ForReading, False)
        Do While Not tsTextIn.AtEndOfStream
            strFileData = Split(tsTextIn.ReadLine, mvarDelimiter)
            oDict.Add strFileData(0), strFileData(1)
        Loop
        tsTextIn.Close
       ReadFile = True
    Else
        Err.Raise -1, "ReadFile", "Tiedostoa ei löytynyt"
    End If
Exit Function
errhandler:
    ReadFile = False
    HandleErrors Err
End Function

Public Function WriteFile() As Boolean
    Dim objFile As New FileSystemObject
    Dim tsTextOut As TextStream
    Dim strFileData As String
    Dim key As Variant
On Error GoTo errhandler
    Set tsTextOut = objFile.OpenTextFile(mvarFilePath, ForWriting, True)
    For Each key In oDict.Keys
       tsTextOut.WriteLine key & mvarDelimiter & oDict(key)
    Next
    tsTextOut.Close
Exit Function
errhandler:
    WriteFile = False
    HandleErrors Err
End Function

Public Function CheckPassword(strUserName As String, strPassword As String) As Boolean
On Error GoTo errhandler
    If Trim(strUserName) = "" Or Trim(strPassword) = "" Then Err.Raise -3, "CheckPassword", "Tyhjä parametri"
    If oDict.Exists(strUserName) Then
        If oDict(strUserName) = strPassword Then
            CheckPassword = True
        Else
            CheckPassword = False
        End If
    Else
        CheckPassword = False
    End If
Exit Function
errhandler:
    CheckPassword = False
    HandleErrors Err
End Function

Public Function ChangeUserData(strOldUserName As String, strNewUserName As String, strPassword As String, Optional bSaveToFile As Boolean = True) As Boolean
On Error GoTo errhandler
    If Trim(strNewUserName) = "" Or Trim(strNewUserName) = "" Or Trim(strPassword) = "" Then Err.Raise -3, "ChangeUserData", "Tyhjä parametri"
    If oDict.Exists(strOldUserName) Then
        If strOldUserName <> strNewUserName Then
            oDict.Add strNewUserName, strPassword
            oDict.Remove strOldUserName
        Else
            oDict(strOldUserName) = strPassword
        End If
        If bSaveToFile Then WriteFile
        ChangeUserData = True
    Else
        Err.Raise -2, "ChangeUserData", "Muutettavaa käyttäjätunnusta ei löydy:" & strOldUserName
    End If
Exit Function
errhandler:
    ChangeUserData = False
    HandleErrors Err
End Function

Public Function AddUserData(strUserName As String, strPassword As String, Optional bSaveToFile As Boolean = True) As Boolean
On Error GoTo errhandler
    If Trim(strUserName) = "" Or Trim(strPassword) = "" Then Err.Raise -3, "AddUserData", "Tyhjä parametri"
    If Not oDict.Exists(strUserName) Then
        oDict.Add strUserName, strPassword
        If bSaveToFile Then WriteFile
        AddUserData = True
    Else
        Err.Raise -2, "AddUserData", "Käyttäjätunnus on jo varattu:" & strUserName
    End If
Exit Function
errhandler:
    AddUserData = False
    HandleErrors Err
End Function

Public Function DeleteUserData(strUserName As String, Optional bSaveToFile As Boolean = True) As Boolean
On Error GoTo errhandler
    If Trim(strUserName) = "" Then Err.Raise -3, "DeleteUserData", "Tyhjä parametri"
    If Not oDict.Exists(strUserName) Then
        oDict.Remove strUserName
        If bSaveToFile Then WriteFile
        DeleteUserData = True
    Else
        Err.Raise -2, "DeleteUserData", "Käyttäjätunnus ei löydy" & strUserName
    End If
Exit Function
errhandler:
    DeleteUserData = False
    HandleErrors Err
End Function

Private Function HandleErrors(oErr As ErrObject)
    Dim oErrFile As New FileSystemObject
    Dim tsErrors As TextStream
    Me.ErrNumber = oErr.Number
    Me.ErrDescription = oErr.Description
    Me.ErrSource = oErr.Source
    Set tsErrors = oErrFile.OpenTextFile(App.Path & "\ErrLog.txt", ForWriting, True)
    tsErrors.WriteLine Now() & " : " & oErr.Number & " : " & oErr.Source & " : " & oErr.Description
    tsErrors.Close
End Function

Voit testata luokkaa seuraavasti:

1. Laita lomakkeelle 5 painiketta joiden kaikkien nimeksi laitat cmdManage ja lisäksi tekstikentät: txtUserName, txtNewUserName, txtPassword

2. Kopioi allaoleva koodi lomakkeelle:

Dim pwd As New Password
Private Sub Form_Load()
    Set pwd = New Password
    pwd.Delimiter = ";"
    pwd.FilePath = App.Path & "\PwdFile.dat"
    If Not pwd.ReadFile Then
        MsgBox "Virhe ladattaessa salasanoja"
    End If
End Sub
Private Sub cmdManage_Click(Index As Integer)
    Select Case Index
    Case 0
        If Not pwd.AddUserData(txtUserName.Text, txtPassword.Text) Then
            MsgBox "Virhe lisättäessä salasanaa:" & pwd.ErrDescription
        End If
    Case 1
        If Not pwd.DeleteUserData(txtUserName.Text) Then
            MsgBox "Virhe poistettaessa salasanaa: " & pwd.ErrDescription
        End If
    Case 2
        If Not pwd.ChangeUserData(txtUserName.Text, txtNewUserName.Text, txtPassword.Text) Then
            MsgBox "Virhe muokattaessa salasanaa: " & pwd.ErrDescription
        End If
    Case 3
        pwd.WriteFile
    Case 4
        If Not pwd.CheckPassword(txtUserName.Text, txtPassword.Text) Then
            MsgBox "Väärä käyttäjätunnus tai salasana"
        Else
            MsgBox "Oikea salasana"
        End If
    End Select
End Sub
Private Sub Form_Unload(Cancel As Integer)
    pwd.WriteFile
End Sub

Ja kun käytät tätä koodia muista mainita projektissasi mistä sen sait ja kuka sen koodasi ("Tämänkin loistavan koodin sain Ohjelmaputkasta - Antti K:lta")

Antti [02.03.2004 00:27:13]

#

Tein muuten siitä myös koodivinkin, johon lisäsin tuon datatiedoston kryptauksen...


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta