Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB6: SendKeysissä probleema *Visual Basic*

Sivun loppuun

Nobo [08.11.2005 22:16:14]

#

Sellainen ongelma, että kun on tekstiboksi, johon voi ohjelman käyttäjä kirjoittaa tekstiä ja painamalla numpadista 1 numeroa, se ohjelma kirjoittaa SendKeysillä sen tekstiboksin sisällön. Mutta, jos laittaa siihen jotain tiettyjä erikoismerkkejä niin ohjelma kräshää ja tulee virheilmoitus: "Run-time error '5': invalid procedure call or argument" ja joitain erikoismerkkejä se ei taas ollenkaan kirjoita.
Siis, jos tajusitte niin auttakaa! :)

Koodia:
            If GetASyncKeyState(&H61) Then
            SendKeys "{Backspace}", True
            SendKeys (Text1.Text), True

Jäynis [10.11.2005 16:56:27]

#

Jospa tästä ois apua.
Jotkin merkit katos tai anto tuon virheilmotuksen omissa testeissä mutta msdn opetti että jotkin merkit tarvii laittaa {} sisään esim "(" toimi kun laitto "{(}". Eli jotta voisit suoraan sendkeys(text1.text) täytys sen tekstilootan sisältö käsitellä siten että niiden merkkien jotka muuten ei toimi ympärillä ois {} merkit.

Edit: Jos käytössä vb:kutonen niin funktio Replace saattaa auttaa ;)

Nobo [10.11.2005 17:22:25]

#

Hei. Juu VB 6 käytössä, mutta voisitko neuvoa vähän tuota Replacen käyttöä?

Jäynis [10.11.2005 17:36:20]

#

Ei millään pahalla mutta pienellä etsinnällä ja tutkimisella varmasti löytäisit täältä putkastakin esimerkkejä ja vinkkejä.

Noh, kilttinä kristittynä autan Noboa mäessä :)

Private Sub Command1_Click()
    Dim teksti As String
    'Eli Replace palauttaa muokatun tekstin, tässä tapauksessa muuttujaan teksti
    'Parametreiksi ensin muokattava teksti, sitten korvattava
    'kirjain/teksti ja sitten korvaava merkki/teksti.
    'Replacessa on vielä joitakin muitakin parametreja mutta
    'niitä en millään jaksa ruveta selittään ja luulen että pärjäät ihan hyvin näilläkin.
    teksti = Replace(Text1.Text, "a", "(a)")
    MsgBox "Muokattiin teksti: " & Text1.Text & Chr(13) & _
    "tekstiksi: " & teksti
End Sub

Blaze [10.11.2005 17:42:33]

#

https://www.ohjelmointiputka.net/hak/?kieli­=Visual Basic&nimi=Replace

Nobo [10.11.2005 17:46:01]

#

Ohhoh. :D Olisin tosiaan voinut etsiäkin, luulin vain etten löydä, koska jo monta tuntia eilen etsin ohjeita eri tapoihin, millä tuon voisi korjata, mutta ei tullut mieleen etsiä replaceen ohjeita.
No, mutta kiitoksia todella paljon. :-)
Voin laittaa kiitoksiin nimenne, jos haluatte..?

EDIT: Harmi vain, ettei tuo toimi. :l MsgBoxissa kyllä lukee, mitä on replacettu, mutta Textboxin sisältö pysyy normaalina. :l

Jäynis [10.11.2005 17:52:57]

#

Voit laittaa "Jäynis" jos siltä tuntuu :D. Ihan uteliaisuuttani kysyn, mitä säädät?

Edit: Ja ei tuon oo tarkotuskaan muuttaa textboxin sisältöä.
Niinku siinä lukee, Replace palauttaa tekstin teksti nimiseen muuttujaan. Jos haluat muuttaa texstboxin sisältöä niin se tapahtuu näin

text1.text="Teksti jonka halusin textboxiin"

Ja tuon tekstin sijasta laitat vaan Replacen palauttamaan tekstin textboxiin tahi asetat textboxin.text arvoksi muuttujan teksti sisällön.

Mut suosittelisin sua kertaamaan vb-oppaan

*Ja valmista koodiahan ei saa antaa* XD

hunajavohveli [10.11.2005 17:54:24]

#

Pistä se funktion palautusarvo TextBoxiin sen sijaan, että antaisit sen parametriksi MsgBoxille.

hunajavohveli [10.11.2005 18:03:19]

#

Palautusarvo on se arvo, minkä funktio palauttaa.
https://www.ohjelmointiputka.net/oppaat/opas.php?tunnus=vbo_5

Edellisessä tapauksessa arvo sijoitetaan teksti-muuttujaan. Muuttujan sijaan pistät sen textboxiin.

Edit: Menitpä sitten poistamaan viestisi. :P

Nobo [10.11.2005 18:07:42]

#

Katos katos, kiitosta vaan kaikille. Nyt sain toimimaan, ainakin toistaiseksi.

Ja Jäynis, kysyit, että mitä säädän niin tässä vastaus:
Säädän sellaista ihmeellistä softaa (a.k.a. "flood-ohjelma), elikkä tässä on 9 tekstilaatikkoa ja painamalla Numpadista 1-9 -näppäimiä, se ohjelma kirjoittaa SendKeysin avulla näppäimistöllä sen tekstilaatikon tekstin.. jos tajusit?

Screenshotti ja ohjelma ladattavissa myöhemmin.
PS. Mun eka ohjelma VB:llä.

EDIT: Hunaja, juu, menin poistamaan, koska se oli vain väliaikainen muistikatkos. :D


EDIT 2: Ähh, ongelmat jatkuu. :/ Miten saan niin, että nyt kun mulla on SendKeysissä tällänen koodi:

SendKeys Replace((Text1.Text), "[", "{[}"), True

eli nyt kun tuo replacee [ -merkin {]}:ksi niin, miten saan sen replacemaan myös ] -merkin {]}:ksi

Blaze [10.11.2005 18:22:54]

#

No ihan samalla tavalla?

Nobo [10.11.2005 18:25:14]

#

Blaze, täh? Tarkoitan siis, että millä ihmeellä saan tuohon _samaan_ SendKeys kohtaan '2 replacea'?

Merri [10.11.2005 18:30:09]

#

Laittamalla toisen Replacen olemassaolevan ympärille.

Replace$(Replace$((Text1.Text), "[", "{[}"), "]", "{]}")

Jäynis [10.11.2005 18:31:47]

#

Ei se tämän kummempaa oo.

Dim teksti As String
teksti = Replace(Text1.Text, "[", "{[}")
teksti = Replace(teksti, "]", "{]}")
SendKeys teksti, True

Eli muutat text1.text haluamaasi muotoon ja palautat sen muuttujaan teksti, ja muutat muuttujan teksti sisältöä haluamallasi tavalla ja palautat sen samaiseen muuttujaan. Tätä voi jatkaa niin kauan kunnes kaikki on kuten pitää :)

Edit:Hidas minä, noinkin se onnistuu.

Nobo [10.11.2005 18:54:22]

#

Kiitoksia taas kerran. :-) Nyt toimii ainakin toistaiseksi.

EDIT: Toimi juu tuo kohta, mutta uusi oknelma löytyi.
Miten saan " -merkit replacettua tyhjiksi? Kokeilin

..., "{"}", "")

, mutta se ei toiminut eikä toiminut myöskään pelkkä

, """, "")

.

Jäynis [10.11.2005 19:15:38]

#

Visual basicissa pitää laittaa kaksi " merkkiä merkkijonon sisään että se näkyy yhtenä merkkinä, en oikein osaa selittää mut tää toimi mulla.

Text1.Text = Replace(Text1.Text, """", "")

Edit: Oppaassa osassa 2 kerrotaan kyseisestä asiasta.

Nobo [10.11.2005 19:20:32]

#

Kiitos Jäynis. Katsoin kyllä eilen nuo oppaat läpi, mutta enpä muistanut tuollaista kohtaa siellä, joten kysyin täällä.

Blaze [10.11.2005 19:26:48]

#

Joko noin, tai sitten Chr-funktiolla:
Text1.Text = Replace(Text1.Text, Chr$(34), "")

Nobo [10.11.2005 21:43:55]

#

Ähh, pakko kysyä vielä yksi juttu.
Etsin Googlesta ja Ohjelmointiputkasta (muttei löytynyt mistään) keinoa, miten saan vielä { -merkit toimimaan. Koitin replacella "{", "{{}", muttei toiminut.

Onko olemassa saman tapaista koodia kuin tuo "Chr$(34)", mutta vain { ja } -merkille?

Jäynis [10.11.2005 22:05:21]

#

Merkin Ascii koodi selviää Asc() funkkarilla

MsgBox "Merkin { ascii koodi: " & Asc("{")

Näyttäs että { merkin ascii koodi on 123
eli

Chr(123)

Käy se näinkin

Chr(Asc("{"))

Mutta ei mulla ollut mitään ongelmia kun testailin
Koodi:

dim a as String
a = "abc{dfg"
a = Replace(a, "{", "{{}")
SendKeys a, True

Blaze [10.11.2005 22:07:52]

#

http://www.asciitable.com

Nobo [10.11.2005 22:23:54]

#

Kiitos taas, mutta nyt en kyllä ymmärrä. :S
(, ), { eikä } toimi vaan tulee virheilmoitus:
"Run-time Error '5':

Invalid procedure call or argument" tästä kohdasta:

SendKeys Replace$(Replace$(Replace$(Replace$(Replace$(Replace$(Replace$(Replace$(Replace$(Replace$((Text1.Text), "[", "{[}"), "]", "{]}"), "%", "{%}"), "+", "{+}"), "(", "{(}"), ")", "{)}"), "^", "{^}"), "~", "{~}"), "{", "{{}"), "}", "{}}"), True

Jäynis [10.11.2005 22:50:44]

#

Huomaan ainakin ongelman noiden {} merkkien kanssa. Koska kun olet tehnyt yhden replacen niin noita merkkejä on enemmän kuin alkuperäisessä versiossa. Noh, jospa koodi selvittäs vähän enemmän

Dim a As String
a = "{tekstiä}"
a = Replace(a, "{", "{{}")
'Tässävaiheessa a on: {{}tekstiä} ja kaikki hyvin
a = Replace(a, "}", "{}}")
'Ja tässävaiheessa: {{{}}tekstiä{}} ja kaikki ei ole hyvin

Ei tule nyt mitään ratkasua mieleen, ainakaan mitään kovin yksinkertaista. Ilmottele tähän jos jotain keksit

Merri [11.11.2005 01:16:18]

#

Oookkei. Tuossa vaiheessa kannattaa jo unohtaa stringit ja vaihtaa byte arrayn puolelle. Kikkakolmonen:

' pastea uuden projektin formille nopeaa testiä varten
Option Explicit

Private Sub Form_Load()
    Dim barTemp() As Byte, barOutput() As Byte
    Dim intA As Integer, intB As Integer
    ' muutetaan testistring byte arrayksi
    barTemp = "[]%+TÄSSÄ VÄHÄN MALLITEKSTIÄ()^~{}"
    ' varataan tarpeeksi tilaa lopputulokselle eli koska jokainen merkki
    ' voi pituudeltaan kolminkertaistua, eikä me tiedetä sisältöä
    ' etukäteen, varataan lopputulokselle kolminkertainen määrä tilaa
    ReDim barOutput(UBound(barTemp) * 3 + 2)
    ' stringien sisältö on kaksi tavua per merkki: siksi step 2
    For intA = 0 To UBound(barTemp) Step 2
        ' muutetaan yksi tavu string-merkiksi koodaamisen helpottamiseksi
        ' nopeampaa olisi vain käsitellä lukuina, mutta en jaksa luntata koodeja
        ' selkeämpää näin :)
        Select Case ChrW$(barTemp(intA))
            Case "[", "]", "%", "+", "(", ")", "^", "~", "{", "}"
                ' muuta sitten AscW luvuksi, minä en jaksa lunttia
                barOutput(intB) = CByte(AscW("{"))
                barOutput(intB + 2) = barTemp(intA)
                barOutput(intB + 4) = CByte(AscW("}"))
                ' siirry kolme merkkiä eteenpäin lopputuloksessa
                intB = intB + 6
            Case Else
                ' kopioi haluttu tavu
                barOutput(intB) = barTemp(intA)
                ' siirry merkki eteenpäin lopputuloksessa
                intB = intB + 2
        End Select
    Next intA
    ' sitten siistitiään lopputuloksen koko (eli tiputetaan käyttämätön data pois)
    ReDim Preserve barOutput(intB - 1)
    ' ja mallin vuoksi: ulosta
    MsgBox CStr(barOutput)
End Sub

Tästä voisi sitten tehdä vaikka oman funktionsa. Varoituksena vielä, että tämä toimii vain ANSI-moodissa eikä ota muokkauksetta Unicodea huomioon. Normaalistihan VB:n stringit voivat sisältää Unicodea, tosin kauhean monet tässä maanosassa eivät siitä paljoa välitä.

Käytän AscW ja ChrW$ funktioita, koska ne ovat nopeampia kuin Asc ja Chr$. Tosin nopeampaa olisi olla aivan kokonaan ilman niitä. Tosin eipä tässä tapauksessa ole nopeudella väliä, kunhan vain yleisesti valistan.

Tuo koodi muuten näyttää pidemmältä kuin on, yli puolet on kommentteja :)

Nobo [11.11.2005 15:48:43]

#

Öö tota Merri.. En oikein tajua tota esimerkkiä? :-S
Pitäisikö tuossa esimerkissä tulla MessageBox, jossa lukee tuo "[]%+TÄSSÄ VÄHÄN MALLITEKSTIÄ()^~{}"?

EDIT: Hmm, kun lisäsin nuo { ja } -merkin siihen replaceen niin koko hökötys lakkasi toimimasta. Eli siis muutkaan kuin (, ), {, } -merkitkään ei toiminut. Nyt otin { ja } pois niin toimii kaikki muu paitsi { ja }.

Jäynis [11.11.2005 18:30:33]

#

No voit käyttää Merrin koodia vaikka näin:

'tässä esimerkki Merrin koodin käytöstä
Private Sub Form_Load()
    Dim teksti As String

    teksti = "{tekstikoodia~+%^() [  ]}"
    MsgBox teksti


    'Ja käytät näin
    teksti = Replace2(teksti)
    'Toi funktio muuttaa automaagisesti merkkien []{}()+%^~ ympärille merkit {}
    'joten et tarvi enää sitä ..=Replace(Replace(Replace.. juttua
    'Toi kääntää ne kaikki
    MsgBox teksti
End Sub
'Koppaat vain tuon alla olevan Funktion omaan projektiin
Private Function Replace2(teksti As String) As String
    Dim barTemp() As Byte, barOutput() As Byte
    Dim intA As Integer, intB As Integer
    ' muutetaan testistring byte arrayksi
    barTemp = teksti
    ' varataan tarpeeksi tilaa lopputulokselle eli koska jokainen merkki
    ' voi pituudeltaan kolminkertaistua, eikä me tiedetä sisältöä
    ' etukäteen, varataan lopputulokselle kolminkertainen määrä tilaa
    ReDim barOutput(UBound(barTemp) * 3 + 2)
    ' stringien sisältö on kaksi tavua per merkki: siksi step 2
    For intA = 0 To UBound(barTemp) Step 2
        ' muutetaan yksi tavu string-merkiksi koodaamisen helpottamiseksi
        ' nopeampaa olisi vain käsitellä lukuina, mutta en jaksa luntata koodeja
        ' selkeämpää näin :)
        Select Case ChrW$(barTemp(intA))
            Case "[", "]", "%", "+", "(", ")", "^", "~", "{", "}"
                ' muuta sitten AscW luvuksi, minä en jaksa lunttia
                barOutput(intB) = CByte(AscW("{"))
                barOutput(intB + 2) = barTemp(intA)
                barOutput(intB + 4) = CByte(AscW("}"))
                ' siirry kolme merkkiä eteenpäin lopputuloksessa
                intB = intB + 6
            Case Else
                ' kopioi haluttu tavu
                barOutput(intB) = barTemp(intA)
                ' siirry merkki eteenpäin lopputuloksessa
                intB = intB + 2
        End Select
    Next intA
    ' sitten siistitiään lopputuloksen koko (eli tiputetaan käyttämätön data pois)
    ReDim Preserve barOutput(intB - 1)
    ' ja mallin vuoksi: ulosta
    Replace2 = CStr(barOutput)
End Function

Koodin toimintaa en rupea selventämään koska minusta tuo on
melko hyvin kommentoitu

Nobo [11.11.2005 20:56:38]

#

Ahaa, juu nyt kässäsin. :D Kiitos taas. Kokeilen vähän myöhemmin, saanko toimimaan.

Nobo [27.11.2005 13:17:29]

#

No, kesti vähän pitempää kuin "myöhemmin", mutta hyvin sain toimimaan. :) Kiitos.
Mutta nyt tuli taas uusi virhe. Jos se tekstiboksi on tyhjä, jossa käytän tota replace2:sta, niin tulee virhe "Subscript out of range". Miten korjaan?

hunajavohveli [27.11.2005 13:55:06]

#

No jos se boksi on tyhjä, niin sitten et käytä sitä replace2:sta?

Nobo [27.11.2005 14:02:36]

#

No juu.. Taas meni lujaa ja ideoita lensi, kun vasta heräsin. :D Voihan sen niinkin tehdä.

Merri [27.11.2005 16:08:47]

#

Voit lisätä tuohon Replace2-funktioon Dimien jälkeen seuraavan rivin:

If LenB(teksti) = 0 Then Exit Function

Jos ihmettelet miksi käytän LenBiä, niin se johtuu siitä että se on nopein tapa tarkistaa stringin pituus.

Nobo [27.11.2005 18:16:26]

#

OK, kiitos Merri. Tuo koodirivi helpottikin todella paljon.
Olisin lähtenyt ite ties mitä säätämään siihen. :D


Sivun alkuun

Vastaus

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

Tietoa sivustosta