Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB6 ja Crystal tulostusongelma

Sivun loppuun

timotaikuri [09.12.2015 12:21:02]

#

Uusi palstan käyttäjä tässä moi.
Tällainen ongelma josta ei millään meinaa päästä eroon.
VB6:lla tehdystä exestä tulostetaan erillisiin Crystal Reportsilla (versio 9) tehtyihin .rpt tiedostoihin.
Satunnaisesti (ja aika usein) heittää tulostettaessa ohjelmasta pihalle. Ei sen kummempaa virheilmoitustakaan, kuin vain että ohjelma lakkasi toimimasta.
Sellainen huomio että kun exen avaa ja menee eka kerran tulostamaan jostain formista, niin tulostus onnistuu ok. Ohjelman ollessa auki ja tulostettaessa samaan pohjaan muutaman minsan päästä, heittää pihalle satavarmasti.
Olen laitellut koodiin kyllä ns. tappamiset tyyliin Set report=Nothing jne.
Onko muilla vastaavia ongelmia ja mikä neuvoksi?
Alla koodia, kippaa tuon Report.Database.SetDataSource -rivin kohdalla.
adoPrintData on recordsettiin avattu tietue, ja se on kyllä tuossa kohtaa aina auki ja on tietueita.

Dim crystal As New CRAXDRT.Application
Set crystal = Nothing
Dim Report As New CRAXDRT.Report
Set Report = Nothing
Set crystal = New CRAXDRT.Application

Set Report = crystal.OpenReport("c:\tulostepohjat\pohja1.rpt", 1)
Report.DiscardSavedData
Report.Database.SetDataSource adoPrintData, 3
Report.PrintOut True, 1

Set Report = Nothing
Set crystal = Nothing

Mod. lisäsi kooditagit!

groovyb [10.12.2015 20:12:39]

#

Oletko yrittänyt ottaa mahdollista virhettä try catchillä kiinni?

timotaikuri [10.12.2015 20:19:52]

#

groovyb kirjoitti:

(10.12.2015 20:12:39): Oletko yrittänyt ottaa mahdollista virhettä try...

En. Mitenkäs tuollainen onnistuu?

Metabolix [10.12.2015 20:23:07]

#

Oletko mielestäsi käyttänyt New-komentoja fiksusti? En toki VB6:lla koodaa, mutta tuo näyttää aika oudolta, ja netissä kerrotaan, että juuri VB6:n kohdalla koodi toimii vielä kummallisemmin kuin samanlaiset rivit muissa kielissä. Kokeilepa muuttaa koodi tällaiseksi:

Dim crystal As CRAXDRT.Application
Dim report As CRAXDRT.Report

Set crystal = New CRAXDRT.Application
Set report = crystal.OpenReport("c:\tulostepohjat\pohja1.rpt", 1)
report.DiscardSavedData
report.Database.SetDataSource adoPrintData, 3
report.PrintOut True, 1

Set report = Nothing
Set crystal = Nothing

En tiedä, korjaako tämä kokemaasi virhettä, mutta ainakin koodi on selvempi.

Edit: Korjasin linkin.

groovyb kirjoitti:

Oletko yrittänyt ottaa mahdollista virhettä try catchillä kiinni?

Onkohan VB6:ssa sellaisia?

Grez [10.12.2015 20:47:31]

#

Metabolixin koodi on kylläkin täysijärkisempää kuin timotaikurin alkuperäinen koodi, mutta näyttäisi käytännössä tekevän täsmälleen saman. (Ainakin jos niitä käyttävä koodi on kokonaisuudessaan tuossa). Että sikäli muuttaminen tuskin korjaa varsinaista ongelmaa.

Vaikka koodista voisi kuvitella, niin 1. ja 3. rivi eivät luo objekteja eivätkä 2. ja 4. rivit poista niitä. (Koska VB6:n ...As New... tyyppinen määrittely tarkoittaa että objekti luodaan silloin, kun objektimuuttujaa joka on Nothing käytetään. Asettaminen ei ole käyttöä.

VB6:ssa ei tosiaan ole Try Catch -mallia, mutta tokihan siellä voi tehdä

On Error Goto Virheenkäsittelijä
'..Koodia
Exit Sub 'tms / Poistutaan ennen virheenkäsittelijää
Virheenkäsittelijä:
'Err -objektissa on tietoa virheestä

timotaikuri [10.12.2015 21:28:16]

#

Muutin koodin Metabolixin mukaiseksi. Kokeilin tulostusta 10 x peräjälkeen,välillä parin minuutin tako, ei kaatunut kertaakaan, eli varovaisen toiveikas. Huomenna testiä isommalla massalla, näkee sitten korjautuiko.
Grez: Toki virheenkäsittelijä on päällä (MsgBox Err.Description, jne) mutta eipä se ole mitään auttanut koska viskaa ohjelmasta ulos kertomatta mitään syytä.

timotaikuri [11.12.2015 09:13:28]

#

Eipä tuo Metabolixin koodi auttanut ongelmaan. Sellainen huomio että kun tulostaa peräjälkeen toistuvasti useita kertoja, niin ei kippaa ulos.
Kun pitää tulostamisen välillä vähintään 2 min tauon (exe auki koko ajan), niin kippaa varmasti ulos.

Grez [11.12.2015 15:40:17]

#

Olisinkin ollut yllättynyt, jos olisi auttanut, kun mitään todellista muutosta ei tapahtunut.

Jos systeemi ei ole hirveän laaja, niin tekisin sen uusiksi VB.Netillä (tai no oikeastaan C#:lla). Tuo VB6:n kanssa tappelu käy äkkiä turhauttavaksi.

timotaikuri [11.12.2015 17:43:48]

#

Systeemi on iso, kynnys tehdä projekti uudelleen c# on suht iso, eikä asiakasta saa tätä millään maksamaan.
C# on kyllä hankittu ja koneella mutta pari kertaa sitä kokeiltua tuntuu
työläältä kalulta, yksinkertainen comboboxiin datan lataaminenkin vaikutti monimutkaisemmalta kuin vb6:ssa.
En vielä luovuta, koska tiedän että laajasti asiakkailla käytössä olevia, vb6/crystal kaluilla tehtyjä ohjelmia pelittää 100% ...
Täytyisköhän laittaa kyssäriä tuonne crystalin tukeen, lienee nykyisin sapin omistuksessa.

groovyb [13.12.2015 21:47:40]

#

Jos systeemi on iso, miten olet liittänyt kaatumisen tulostamiseen, jos itse tulostaminen ei edes kaada sovellusta?

timotaikuri [14.12.2015 09:31:18]

#

Tulostaminen rpt:hen juurikin on se mikä kaataa sovelluksen. Muuten systeemi pyörii ongelmattomasti, grideihin lataaminen, tietokantapäivitykset jne.

Grez [14.12.2015 11:05:15]

#

Tuossa ei kuitenkaan ole ilmeisesti koko koodi, eli et voi varmaksi tietää että vika on juuri tuossa? Ainakin adoPrintData taitaa olla jossain muualla määritelty.

timotaikuri [14.12.2015 12:20:50]

#

adoPrintData (recordset) avataan ennen noita rivejä näin:

Dim adoPrintData As ADODB.Recordset
Set adoPrintData= CreateObject("ADODB.Recordset")
adoPrintData.CursorLocation = adUseClient
Dim mSQL as string

mSQL="SELECT fiel1,field2 FROM taulu1 WHERE field1=1"
adoPrintData.Open mSQL, gAdocnnClient, adOpenKeyset, adLockOptimistic, adCmdText

(Tuo gAdocnnClient on projektin loginissa avattu tietokantayhteys)

Muuta koodia ei ole tulostamisessa.
Olen laitellut rivien väleihin Msgboxeja jotta saan selville missä kohtaa kilahtaa ulos ja se on nimenomaan tuon SetDataSource-rivin kohdalla.

Mod. lisäsi kooditagit!

Grez [14.12.2015 13:25:17]

#

Menisikö toi gAdocnnClient sitten jotenkin jumiin tai epämääräiseen tilaan, joka aiheuttaisi kaatumisen.

timotaikuri [14.12.2015 14:54:08]

#

Testasin tuonkin laittamalla tuohon koodia joka sulkee gAdoCnnClientin ennen SetDataSource riviä yhteyden ja avaa sen uudelleen.
Muutaman kerran tulosti ok jonka jälkeen taas ohjelmasta pihalle.
Ongelma liittynee crystalin johonkin bugiin tms, rpt ei osaa ottaa toistuvasti 100% varmuudella clientista dataa vastaan. Tämä on minun olettamukseni.
Kaatumista ei tapahtuisi jos vb.exen sulkisi joka kerta ennen tulostusta ja avaisi uudelleen samaan tilanteeseen missä oltiin, mutta sellaisen koodaaminen on aika haastava homma.

Grez [14.12.2015 15:12:04]

#

Yleisesti ottaen tuollaisten ongelmien jossa koko ohjelma vaan katoaa ilman virheenkäsittelyyn menemistä on haastavaa. Jos en saisi ongelmaa mitenkään muuten korjattua niin saattaisin jopa tehdä tuon yhden ongelmaosion jollain muulla kielellä ja kutsua sitä erillistä modulia VB:stä. Kun siis kerran koko systeemiä ei pysty kerralla päivittämään nykyaikaan.

groovyb [14.12.2015 15:21:28]

#

voiko olla mahdollista, että .rpt tiedosto on lukitussa tilassa?

Seuraavanlaisen pätkän löysin ko. tarkistuksesta:

' Return True if the file is locked to prevent the desired
' access.
Private Function FileIsLocked(ByVal filename As String, _
    Optional ByVal for_write As Boolean = True) As Boolean
Const PERMISSION_DENIED As Integer = 70
Dim fnum As Integer
Dim err_number As Integer

    On Error Resume Next
    fnum = FreeFile
    If for_write Then
        Open filename For Append As #fnum
        err_number = Err.Number
    Else
        Open filename For Input As #fnum
        err_number = Err.Number
    End If
    Close #fnum

    On Error GoTo 0
    If err_number = 0 Then
        FileIsLocked = False
    ElseIf err_number = PERMISSION_DENIED Then
        FileIsLocked = True
    Else
        Err.Raise err_number
    End If
End Function

timotaikuri [14.12.2015 19:53:35]

#

Laitoin tuon FileIsLocked funktion projektiini ja tarkistuttamaan josko .rpt on jäänyt lukituksi ennen riviä ...SetDataSource..
Tein Timerin joka pyörittää 5 sekunnin välein tuota mun koodia (disabloin Report.PrintOut -rivin ettei tulosta turhaan)
Sellaiset 10-15 kertaa pyörittää ok ennenkuin heittää softasta pihalle ennen SetDataSource-riviä, kertomatta mitään vihjaavaa syytä.
Kyllähän tämä alkaa vaikuttamaan yhä selvemmin crystalin ongelmalta, tai sitten joku olennainen koodinpätkä tuosta minulta puuttuu.

groovyb [14.12.2015 21:44:29]

#

Eikös se tarkistus pidä olla ennen crystal.OpenReport kutsua, siinähän tuo filu napataan?

timotaikuri [15.12.2015 08:56:42]

#

Siirsin tarkistusfunktion tuon crystal.OpenReport rivin yläpuolelle.
Ei antanut kertaakaan tietoa että .rpt olisi lukittuna, eikä näin auttanut ongelmaan. Ohjelma kippaa tuosta SetDataSource -rivistä.

groovyb [15.12.2015 09:28:08]

#

Seuraavaksi voisit kokeilla tarkastaa tietokantayhteyden tilan ennen käyttöä, ja sallia haun vain kun tila == 1 (Open). Mahdollisesti voisit myös sulkea yhteyden käytön jälkeen, ja avata yhteyden uudelleen kun kantaa seuraavaa kerran tarvitaan.

ADO State Property

timotaikuri [15.12.2015 10:35:45]

#

Tavallaan tietokantayhteys on tullut jo aikaisemmin testattua tuolla jossa keskusteltiin gAdoCnnClientistä.
Laitoin nyt ennen SetDatasourcea uuden rivin MsgBox gAdoCnnClient.State ja antaa
aina arvon 1, myös siinä kohtaa luupissa jossa heittää taas pihalle.
Laitoin myös ehdon jos State<>1 niin hypätään SetDataSourcen yli, sama lopputulos.
Kantaan siis yhteys toimii, mutta ei pukkaa rpt:hen dataa toistuvasti ilman kaatumista.
Voisin testata seuraavaksi niin että kopioin samalla rpt-pohjalla
20 erinimisiä rpt-tiedostoja ja kutsun niitä luupissa joka kerta eri nimistä pohjaa. Luuppaus niin kauan kuin on erinimisiä rpt-pohjia.
Saas nähä loppuuko ensin luuppi ennen kippaamista.

Grez [15.12.2015 10:52:15]

#

Tosta ADODB.Connectionin tilan tarkistamisesta ei muuten yleisesti ottaen ole mitään hyötyä. Se antaa 1 vaikka yhteys olisikin katkennut, ellei sitä ole katkaistu ohjelman päästä (Close -komennolla). Sen lukeminen ei siis testaa yhteyden toimivuutta, vaan kertoo vaan mihin tilaan yhteys on ohjelman puolelta jäänyt.

Mutta tosiaan tuskin vika siinä on, kun kerran jo kokeilit avata yhteyden uudelleen.

timotaikuri [15.12.2015 15:49:40]

#

Kopioin identtisiä rpt-pohjia 30 kpl, ja nimesin kunkin filun eri nimellä rtp1,rpt2 jne.
Luuppaus 30x kussakin luupissa eriin rpt, exen sammutus välillä ja taas luuppaus ja tulostus. Sama yht. 5 kertaa -> ei kertaakaan pihalle ohjelmasta.
Mutta pihalle mennään satunnaisesti jos exea ei välillä sulje.
Eli johtopäätös on että ohjelma kaatuu satunnaisesti kun tulostetaan saman exe-session aikana samannimiseen rpt-pohjaan useammin kuin yhden kerran.
Seuraava kysymys onkin miten tuo kaatuminen estetään ilman että tarvii exea sammuttaa välillä. Jollain tapaa rpt-tiedostot pitäisi "nollata" jokaisen tulostuksen jälkeen?

timotaikuri [18.12.2015 21:15:53]

#

Testaukset jatkuneet. Tulostaa kylläkin samaan tiedostonimeen useaan kertaan yhden exe-istunnon aikana mutta näyttää siltä että kun pitää taukoa tulostamisessa esim vähintään minuutin niin sen jälkeen heittää ulos ekalla yrittämällä tauon jälkeen.
Kun tulostaa peräjälkeen vaikka 10 sek tauolla 50 x putkeenkin niin toimii ok.
Onpa mystinen ongelma.
Yhteys kantaan on kyllä koko ajan auki, se on testattu sulkemalla ja avaamalla yhteys aina ennen tulostusta.

Metabolix [19.12.2015 11:59:10]

#

Pystytkö purkkaratkaisuna tulostamaan säännöllisin välein tyhjää tiedostoa (nolla sivua, tai tulostuksen ohjaus tiedostoon), jotta tulostukseen ei tulisi liian pitkää taukoa?

timotaikuri [23.12.2015 14:05:37]

#

Kaatuu toisinaan vaikka ajaisi säännöllisin välein (30 sek) dataa tyhjään tiedostoon.
Uusi havainto. Kun laitan tällaisen rivin
Report.Database.Verify
ennen riviä Report.Database.SetDataSource adoPrintData, 3
niin ei näytä kaatuvan exe koskaan tulostettaessa koneellani, oli sitten taukoa tai ei.
Asiakkaan koneella ei kuitenkaan rivi .Verify toimi, vaan herjaa tuossa kohtaa puuttuvasta ODBC tietolähteen ohjaimesta.
Eli jotain häikkää rpt-pohjassa kuitenkin?

neosofta [12.01.2016 07:30:21]

#

Auttaisikohan jos asentaisit asiakkaasi koneelle Microsoft Data Access Components (MDAC) -paketin.
Toinen todennäköinen ongelma liittyy 64-bittiseen järjestelmään. Miten tahansa, niin suosittelen siirtymään VB.NET / .NET Framework ympäristöön

timotaikuri [14.01.2016 13:13:09]

#

Siirtyminen vb.nettiin ei välttämättä ratkaise ongelmaa, koska olen kuullut että tuossakin ympäristössä crystal kaatuu. Kyseessä siis voi olla crystalin bugi.
Tuosta MDAC paketista, laitatko linkin mistä sen voi ladata.

neosofta [15.01.2016 15:13:43]

#

MDAC 2.8 SDK

timotaikuri [15.01.2016 15:36:03]

#

Tuosta sun linkkisivulta kun katsoo System Requirements, siellä ei mainita windows 7. Kai tuo seiskakoneisiinkin on asennettavissa?

Muuten, kuulin asiakkaalta että tulostus ei kaadu koskaan xp-koneilla, kaatuu vain win7. Eli ongelma liittyy myös 64-bittisyyteen.

neosofta [15.01.2016 16:45:22]

#

Windows Vistassa ja Windows 7:ssa on valmiina tarvittavat komponentit (Windows DAC korvaa MDAC paketin). Ongelma saattaa piillä myös MSADO15.DLL -kirjaston versiossa. Mikäli on halua viritellä Crystalia 64-bittiselle järjestelmälle niin täältä löytyy kamaa/ohjeita 8.5 versiolle

täältä löytyy Crystal Reports 9.0 run-time 64-bittiselle Windowsille


Sivun alkuun

Vastaus

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

Tietoa sivustosta