Funkce a procedury

10. díl - Funkce a procedury

Tomáš Herceg       01.06.2007       VB.NET       32881 zobrazení

Dlouho očekávané pokračování seriálu pro úplné začátečníky. V tomto díle se podíváme na funkce a procedury, vysvětlíme si obor platnosti proměnných a napíšeme si program na hledání prvočísel.

V jubiljním desátém dílu tohoto seriálu se naučíme používat funkce a procedury. Vlastně to již částečně umíme, ale nevíme o tom. Pokud to zjednoduším, procedura je vlastně speciální druh funkce, podobně jako čtverec je jen speciální druh obdélníka. Funkce je blok kódu, kterému předáme nějaké vstupní hodnoty pomocí proměnných (říká se jim argumenty, někdy také parametry), kód se provede a vrátí nějaký výsledek. Procedura žádný výsledek nevrací, ale jinak je stejná.

Funkce i procedura je něco jako taková „černá skříňka“ – něco jí předáme, skříňka něco udělá a pokud je to funkce, vrátí nám výsledek.

Zápisy funkce a procedury vypadají takto:

    'funkce
    Function <NázevFunkce>(<Argument1> As <Typ1>, <Argument2> As <Typ2> ...) As <DatovýTypVýsledku>
        <Kód funkce>
        Return <Výsledek>
    End Function

    'procedura
    Sub <NázevProcedury>(<Argument1> As <Typ1>, <Argument2> As <Typ2> ...)
        <Kód procedury>
    End Sub

Počet argumentů v závorkách záleží na nás - může jich být 5, ale nemusí být ani jeden (v takovém případě se napíše jen otevřená a zavřená závorka). Jakmile proceduru nebo funkci zapíšeme, Visual Basic nám sám před každý argument doplní klíčové slovo ByVal. Má tam svůj význam, zatím si jej ale všímat nebudeme.

Pokud chceme funkci nebo proceduru spustit (zažitý termín je zavolat), musíme jí předat její argumenty. Pokud je to funkce, její výsledek přiřadíme do proměnné:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'při kliknutí na tlačítko provést součet 4 čísel
        Dim soucet As Integer = Suma4(6, 7, -5, 4)
    End Sub

    Public Function Suma4(ByVal c1 As Integer, ByVal c2 As Integer, ByVal c3 As Integer, ByVal c4 As Integer) As Integer
        'funkce, která vrátí součet 4 čísel
        Return c1 + c2 + c3 + c4
    End Function

V této ukázce jsem tedy vytvořil jednoduchou funkci Suma4, které předáme 4 čísla a tato funkce vrátí jejich součet. Je to velmi jednoduchá funkce, kterou se možná ani nevyplatí vytvářet, protože můžeme čísla sečíst rovnou. Ve skutečnosti se funkce používají na poněkud složitější výpočty. Hodnota, která je za klíčovým slovem Return se vrátí jako výsledek funkce. Pokud by byl za řádkem s Return ještě nějaký další kód, už se neprovede. Return totiž vrátí hodnotu a vyskočí z funkce.

Důležité je ale to, že pokud chceme funkci zavolat, zapíšeme její název a do závorky popořadě hodnoty jejích argumentů (to je to Suma4(6, 7, -5, 4)). Čísla 6, 7, -5 a 4 se dosadí do proměnných c1 až c4 a provede se kód uvnitř funkce s těmito proměnnými, v tomto případě se jen vrátí jejich součet. Pokud se podíváme na řádek Dim soucet As Integer = Suma4(6, 7, -5, 4), tak výsledek volání funkce se přiřadí do proměnné soucet. Celý výraz Suma4(6, 7, -5, 4) může být součástí jiného výrazu, krásně mužeme např. napsat Dim a As Integer = 3 * (Suma4(6, 7, -5, 4) + 2) nebo MsgBox(Suma4(1, 2, 3, 4)). Než se začne vypočítávat výsledek celého výrazu, zjistí se nejdřív výsledek funkce a pak se pracuje s ním.

Procedura žádný výsledek nedává, volá se stejně, akorát musí stát na řádku samotná. Může to vypadat například takto:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'při kliknutí na tlačítko zobrazit součet 4 čísel
        UkazSumu(6, 7, -5, 4)
    End Sub

    Public Sub UkazSumu(ByVal c1 As Integer, ByVal c2 As Integer, ByVal c3 As Integer, ByVal c4 As Integer)
        'procedura, která zobrazí součet 4 čísel
        MsgBox(c1 + c2 + c3 + c4)
    End Sub

Procedura zobrazí hlášku se součtem předaných čtyř čísel. Volání této procedury je jen řádek UkazSumu(6, 7, -5, 4).

Aby toho nebylo málo, tak i při volání funkce či procedury můžeme používat výrazy. Přípustné je tedy i například toto (pro přehlednost jsem obarvil každý argument jinou barvou):

UkazSumu(6, Suma4(1, 5, 78, -54), -5 + x, 4 * (7 - t / 39))

Tento zápis je ovšem již na hranici přehlednosti - asi by bylo lepší alespoň výsledek funkce Suma4 nejprve přiřadit do nějaké proměnné a volat proceduru UkazSumu s použitím předvypočítané hodnoty. Nicméně i tento zápis funguje.

Procedury již známe - pracujeme s událostmi komponent

Jak jsem již na začátku předeslal, procedury již trochu známe. Pokud se podíváte na zápis procedury události kliknutí na tlačítko, najdete tam také Sub, End Sub a argumenty. První argument je sender a je to vždy objekt, který událost vyvolal. Druhý argument je e, což jsou doplňující informace k události. Tyto dva argumenty má každá událost jakékoliv komponenty. Dále následuje klíčové slovo Handles, které říká, na kterou komponentu a událost se má procedura napojit.

Takže to, co jsme psali mezi dva řádky, které se objevily při komponentu na tlačítko na formuláři, to byl vnitřek procedury. Tato procedura se zavolala vždy, když nastala událost dané komponenty.

Hledáme prvočísla

Teorii už máme za sebou, nyní nás čeká praktický úkol. Napíšeme aplikaci, která vypíše všechna prvočísla nižší než 1000. Prvočíslo je číslo, které je dělitelné jen jedničkou a samo sebou, ničím jiným. Jednička samotná se mezi prvočísla nepočítá.

Dříve než začneme psát, rozmyslíme si, jak bude program fungovat. A pokusíme se využít co nejvíc věcí, které již umíme. Umíme cyklus For, který provádí určitou operaci pro všechna celá čísla z nějakého intervalu. To se nám velice dobře hodí. Jednoduše uděláme cyklus od 1 do 1000 a vyzkoušíme, jestli je aktuálně procházené číslo prvočíslem. A pokud je, vypíšeme jej do seznamu. Pro správný návrh programu je dobré zamyslet se, která činnost se bude opakovat nejčastěji. A bude to právě zjišťování, jestli je číslo prvočíslo. A pokud se něco často opakuje, i když třeba pro jiné hodnoty, vyplatí se na to udělat funkci. Pak již máme jen skříňku, které se zeptáme "Je trojka prvočíslo?", a dostaneme z ní odpověď ano či ne.

Došli jsme tedy k tomu, že musíme napsat funkci JePrvocislo, které předáme jeden argument i, což bude číslo, na které se ptáme. Funkce bude typu Boolean, protože vrátí True, pokud i je prvočíslo, a False, pokud není. O tom, jestli je nějaké číslo prvočíslo, rozhodneme jednoduše - zkusíme ho vydělit vším možným a pokud najdeme nějaký dělitel kromě jedničky nebo testovaného čísla, prvočíslo to nebude. Zkusíme tedy vydělit číslo i všemi čísly od 2 do i-1 a pokud nějakého dělitele najdeme, prvočíslo to nebude. A jak zjistit dělitelnost? Známe operátor Mod, který vrátí zbytek po vydělení. A pokud je zbytek nula, číslo dělitelné je. Zkoušíme vždy vydělit číslo i číslem, které je čítač cyklu (protože to právě zkoušíme). Funkce tedy bude vypadat takto:

    Function JePrvocislo(ByVal i As Integer) As Boolean
        'zkusíme dělit čísly od 2 do i-1
        For a As Integer = 2 To i - 1
            If i Mod a = 0 Then Return False 'našli jsme dělitele, prvočíslo to není
        Next
        Return True     'je prvočíslo
    End Function

A hlavní program již nebude těžký. Přidejte na formulář tlačítko a seznam (ListBox). Dvakrát klikněte na tlačítko, aby se vygenerovala procedura. Do ní napíšeme zkoušení a vypisování prvočísel. Zkusíme všechna čísla od 2 do 1000 a zavoláme na ně funkci. Pokud vrátí True, přidáme dané číslo do seznamu.

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        For i As Integer = 2 To 1000        'zkusíme čísla od 2 do 1000
            If JePrvocislo(i) Then ListBox1.Items.Add(i) 'pokud i je prvočíslo, přidáme ho do seznamu
        Next
    End Sub

A to je celé. Na první pohled složitá úloha. A bez funkce by byl kód poněkud nepřehledný a složitý.  Pokud strukturu dobře navrhneme, usnadníme si tím mnoho práce. Vždy se snažte úkony, které se často opakují, izolovat do funkce. Nevadí, že jsou po každé pro jiné hodnoty, ty jim lze předat jako argument.

Proměnné a jejich platnost

Možná jste si všimli, že ve funkci i v proceduře máme proměnné i. Přesto se tyto proměnné navzájem neovlivňují. Je načase poodhalit roušku tajemství - záleží, kde proměnnou deklarujeme.

Pokud proměnnou nadeklarujeme uvnitř procedury (příkazem Dim nebo jako argument), platí nám jen v této proceduře. Označujeme ji jako lokální proměnnou, kdekoliv jinde může být proměnná se stejným názvem, ale je to jiná proměnná. Má jiné hodnoty a je v paměti uložena úplně jinde. Tyto dvě proměnné se navzájem neovlivňují. Pokud proměnnou nadeklarujeme mimo proceduru (ale mezi řádky Class a End Class, tedy uvnitř třídy - v našem případě formuláře), platí tato proměnná ve všech procedurách, které jsou v dané třídě (formuláři). Pokud by se ale v některé proceduře objevila deklarace lokální proměnné stejného názvu, tak v té konkrétní proceduře se bude používat proměnná lokální. Pokud proměnnou nadeklarujeme v cyklu, platí jen v tomto cyklu, za ním již ne. Pokud ji nadeklarujeme v podmínce, platí opět jen v té větvi podmínky.

Podobná věc funguje i u procedur a funkcí - pokud použijeme před slovem Sub nebo Function slovo Private, platí daná procedura jen v rámci dané třídy (formuláře). Pokud uvedeme Public, můžeme ji zavolat i z formulářů ostatních. Pokud nadeklarujeme proměnnou mimo proceduru, jen ve třídě, a použijeme místo Dim slovo Public, bude k ní také možno přistupovat z jiných formulářů.

Kouzelné slovíčko ByVal

Jak jsem již dříve upozornil, před každý argument nám Visual Basic automaticky přidá slovíčko ByVal. Znamená to, že pokud předáváme jako argument pouze proměnnou, vytvoří se její kopie a v proceduře či funkci se pracuje jen s touto kopií. Pokud ji tedy uvnitř procedury nebo funkce změníme, n původní předávanou proměnnou to nemá vliv. Pokud bychom slovíčko změnili na ByRef, pracovalo by se uvnitř funkce či procedury s předávanou proměnnou. Pokud ji změníme, změní se i proměnná, kterou jsme předávali při volání. Příklad je zde:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim b As Integer = 10
        Nastav1(b)      'předáme proměnnou přes ByVal
        MsgBox(b)       'výsledkem bude pořád 10, přes ByVal se změna hodnoty neprojeví
        Nastav2(b)      'předáme proměnnou přes ByRef
        MsgBox(b)       'výsledkem je tentokrát 16, přes ByRef se změní i místní proměnná
    End Sub

    Sub Nastav1(ByVal a As Integer)
        a = 5           'změna na proměnné a se neprojeví navenek
    End Sub

    Sub Nastav2(ByRef a As Integer)
        a = 16          'hodnota se promítne do proměnné předané jako a
    End Sub

I když v první proceduře argument změníme, do proměnné b v proceduře události tlačítka se tato změna nepřenese. Argument je totiž ByVal. Druhá procedura ale proměnnou opravdu změní. To můžeme využít, pokud chceme, aby např. funkce vracela více než jeden výsledek - použitím ByRef argumentů nastavíme hodnoty proměnnách, které do funkce předáváme.

ByVal a ByRef má však smysl pouze u proměnných běžných (tzv. primitivních) datových typů (String, Integer, Double, Date, Boolean atd.). Visual Basic nám tyto datové typy zvýrazňuje modře. Pokud ale předáváme pole nebo objekty, vždy se to chová jako ByRef. Vytváření kopií objektů a polí by zabralo mnoho procesorového času a ani toto chování není ve většině případů žádoucí.

To je protentokrát vše. Než se dohrabu k napsání dalšího dílu, můžete si zkusit napsat program, který vypíše prvních 5000 prvočísel (ne od jedné do 5000). A zkuste si také rozmyslet, proč při zjišťování prvočíselnosti stačí procházet čísla pouze od 2 do odmocniny z i a ne až do i - 1.

 

hodnocení článku

3 bodů / 3 hlasů       Hodnotit mohou jen registrované uživatelé.

 

Mohlo by vás také zajímat

Programování Windows Services

Services (služby) jsou jedním ze základních stavebních kamenů programování pro systémy Windows. V článku se budu věnovat jak obecným principům a doporučením, tak konkrétním implementačním postupům.

Windows Presentation Foundation (WPF) - díl 9.: ContentControl, Button a TextBlock

Článěk se věnuje základům důležité komponenty ContentControl a dvěma vizuálním komponentám: Button (tlačítko) a TextBlock (textový blok).

Co je to .NET Framework 4.5?

V tomto článku se snažím nastínit rozdíl mezi .NET 4 a .NET 4.5 z pohledu zpětné kompatibility.

 

 

Nový příspěvek

 

Mr.

1'

csharp|

xml|

css|


'

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Volání procedury s více proměnnými

Dobrý den, vím, že vlákno je již staré, ale stejně se zeptám.

Dokázal by mi někdo poradit, kde dělám chybu..

Píšu jednoduchou věc:

Private Sub CommandButton1_Click()

Dim text As String

Dim text1 As String

text = "dobrý "

tex1 = "den"

zobraz_text (text, text1)

'řádek výše se jeví jako chyba

End Sub

Private Sub zobraz_text(ByVal text As String, ByVal text1 As String)

MsgBox (text + text1)

End Sub





Po zapsání řádku "zobraz_text (text, text1)" hlásí chybu "expected: =".
nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět

OTAZKA CO JE ZITO VOLEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE

Dnes je dnes hercigle vis to

sql|

vbnet|

css|



                        
                    
nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Diskuse: Funkce a procedury

Pridal som do Class Form1 funkciu Function JePrvocislo(ByVal i As Integer) As Booleanale v Error Liste mi vypisuje, že nie je deklarovaná : Error 1 Name 'JePrvocislo' is not declared.

nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět

dim JePrvocislo as boolean

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Diskuse: Funkce a procedury

Zdravím,

potřeboval bych vytvořit vlastní funkci, jejímž výsledkem bude 2 a více hodnot, jako to například dělá funkce LinRegrese v excelu.

Tzn. aby po aplikaci na více buněk v excelu došlo k jejich zaplnění čísly vektoru, které funkce vypočte.

Děkuji za pomoc.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Definuj pole s dvěma hodnotami a pak se v definici funkce na pole odkaz.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Nerozumím, můžete uvést příklad prosím.

Jde mi o funkci, která nebude vracet hodnotu, ale vektor hodnot.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Nevim, co presne potrebujes. Jestli ti budou stacit definovat Public dve promene, do ktere to budes procedurou plnit nebo pro klidne funkce.

Jestli je to vhodne tak pouzij definici "type" ve vb6 nebo "structure" v net. Vic napoveda, protoze to je zaklad. Pokud neco programujes slozitejsiho musis se naucit zaklady.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Diskuse: Funkce a procedury

Dobrý den,

až doposud jsem si se všemy problémy s procedurami a funkcemi ve svých projektech dokázal poradit - nyní jsem ale v koncích a odpověď jsem nenašel ani na tomto webu, ani v knihách, ani na googlu.

Toto je část kódu, která se v projektu velmi často opakuje. Tab1 je dvojrozměrné pole, vždy se jmenuje stejně. Hodnota NJR se mění podle toho, na jakém zrovna pracujeme řádku. ZL2 je uzel, který se mění, podle zvolené hodnoty (nemění se ale hodnota proměnné, ale název!! - (ZL2 vs ZL3 atd...))

Tab1(NJR, 3) = ZL2.FirstChild.NextSibling.InnerText 'JednotkaNakup
Tab1(NJR, 4) = CDbl(ZL2.FirstChild.NextSibling.NextSibling.InnerText) 'CenaProdej
Tab1(NJR, 5) = CDbl(ZL2.FirstChild.NextSibling.NextSibling.NextSibling.InnerText) 'PrumernaCena
Tab1(NJR, 6) = ZL2.LastChild.PreviousSibling.PreviousSibling.InnerText 'Skupina
Tab1(NJR, 7) = CDbl(ZL2.LastChild.PreviousSibling.InnerText) 'MnozstviKDispozici
Tab1(NJR, 8) = ZL2.LastChild.InnerText  'MernaJednotka

Moje představa je taková, že bude procedura nebo funkce, které předám atributy, (NJR a nějakou proměnou místo ZL2) např: Udelatko(NJR, ZL3) a dohází mi to do TAB1 hodnoty. První problém ale je, že nevím jak mám druhý atribut definovat (string to nebude :) ) a také že pole TAB1, (přesto, že je definováno hned pod "public class") do vnitřního kódu nenacpu - procedura to pole nezná.....

Předem díky za případné rady nebo odkazy na články, kde by se dala vyčíst odpověď

nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět

Diskuse: Funkce a procedury

mam sestavic proceduru nebo funkci,ktera zjisti kolik ruznych znaku se vyskytuje v textovem retezci.

a potom mam tk sestavit proceduru nebo program,ktera vypocte prumer dvou vstupnich cisel.

prosim poradte mi :( do 9:15.

nahlásit spamnahlásit spam -3 / 3 odpovědětodpovědět

A to ti není blbé, žádat tady o pomoc při písemce a podvádět, protože ses vysral na přípravu?

nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět

Diskuse: Funkce a procedury

Mam dotaz,

jestli se daji procedury vnorovat? Takto nebo jinak? (takto mi to neslo)

sub procedura1

sub procedura2

end sub

end sub

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Nejdou. Až ve VB 10, který ještě nevyšel, bude k dispozici s novým Visual studiem 2010.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Diskuse: Funkce a procedury

Mám dotaz zdali lze ve VB.net volat proceduru "podle jejího jmena". Ve VBA existuje funkce CallByName kde argumentem je jméno metody. Ve VB jsem našel pouze možnost použití metody Run při volání například makra v excelu podle jeho názvu uloženého v proměnné. Existuje nějaká funkce jejímž argumentem by bylo jméno volané procedury, s tím, že by to byla proměnná (string)?

Za případné naměty či řešení předem děkuji.

Karel

nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět

Tohle je ve VB.NET poměrně obtížné. Musí se použít Reflection, což patří mezi velmi pokročilé techniky, proto se o nich v článku pro začátečníéky nezmiňuji. Navíc tato metoda není úplně čistá, pokud to jde, snažte se jí vyvarovat. Pokud to opravdu nejde, je možné ji zavolat takto:

Public Class Form1
    Public Sub MojeProcedura(ByVal p1 As String, ByVal p2 As String)
        'zobrazit parametry
        MsgBox("ahoj " & p1 & " " & p2)
    End Sub

    Private Sub Form1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Click
        'zavolat proceduru jménem
        Me.GetType().GetMethod("MojeProcedura").Invoke(Me, New Object() {"parametr 1", "parametr 2"})
    End Sub
End Class

nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět

Ve vb 2008 metoda CallByName je funkční pro volání metod nebo vlastností.

nahlásit spamnahlásit spam -2 / 2 odpovědětodpovědět

Diskuse: Funkce a procedury

Mohl by někdo poslat ukázku řešení hledání prvních 5000 prvočísel jen tak pro porovnání.

Dík

nahlásit spamnahlásit spam -3 / 3 odpovědětodpovědět
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim pAdept As Integer = 1
        Dim pCount As Integer = 0
        While Not pCount = 5000
            pAdept += 1
            If JePrvocislo(pAdept) Then
                ListBox1.Items.Add(pAdept)
                pCount += 1
            End If
        End While
    End Sub

nahlásit spamnahlásit spam -4 / 4 odpovědětodpovědět

Diskuse: Funkce a procedury

Vytvářím program u kterého potřebuju, aby když se v Textbox1 objeví třeba číslo 5, tak aby se přešlo na předchozí krok. Nevím jak to mám udělat. Prostě potřebuju, aby se program vrátil na určité místo, kde už byl a od tohoto místa zase pokračoval dál. Zkoušel jsem to pomocí Line, ale nějak mi to nejde.

    Private Sub Button8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click
Line1:
        TextBox1.Text = Label1.Text
        If TextBox1.Text = Label1.Text Then
            Label1.Text = 9
        End If

Line2:
        TextBox2.Text = Label2.Text
        If TextBox2.Text = Label2.Text Then
            Label2.Text = 8
        End If

Line3:
        TextBox3.Text = Label3.Text
        If TextBox3.Text = Label3.Text Then
            Label3.Text = 7
        End If

Line4:
        TextBox4.Text = Label4.Text
        If TextBox4.Text = Label4.Text Then
            Label4.Text = 6
        End If
Line5:
        If TextBox1.Text = 5 Then
            GoTo Line2
        End If
    End Sub

nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět

Pokud se splní podmínka kde textbox1.text = 5 a nic se nezmění,tak se přece splní podmínka i příště a tak pořád dokola. To je nebezpečí používání "GoTo" kde si na to musíte dávat pozor. Jenže vy toho nikdy nedosáhnete, protože v první podmínce, si defacto nastavíte textbox1 na hodnotu 9, takže se nikdy nemůže splnit podmínka že se texboxt může rovnat pěti :-)

Dále, když nastavíte hodnotu textboxu dle hodnoty labelu, tak je zbytečné to znovu vyhodnocovat.

např.

TextBox4.Text = Label4.Text
        If TextBox4.Text = Label4.Text Then
            Label4.Text = 6
        End If

je přece to samé jako

Label4.text = 6

Určitě to půjde lépe vyřešit např. pomocí Select Case.

Možná by bylo lepší popsat čeho chcete dosáhnout, protože mi to nějak nedává smysl.

nahlásit spamnahlásit spam -2 / 2 odpovědětodpovědět

Tu podmínku s tím, že se TextBox1.Text = 5, jsem sin vymyslel. Vytvářím program u kterého potřebuju, aby když se splní určitá podmínka, tak aby se vrátil zpět na určitý krok. Jestli chcete popsat, na co ten program je, tak vám to tedy řeknu.

Bude to program, který bude skládat hlavolam nebo spíš skládačku. Je to čtvercové pole rozdělené na 256 (16 krát 16) políček a 256 dílků (čtverečků), které mají na každé své straně stejné číslo. Dílky se musí do pole poskládat tak, aby strany sousedních dílků měly stejná čísla. Je to vlastně dvojrozměrné domino.

Program vždy vloží dílek na políčko a když tam pasuje nechá ho tam, kdyňepasuje vyndá ho a dá tam jiný. Když tam ale nepasuje žádný (to je ta podmínka o které jsem mluvil na začátku) musí se vrátit na předchozí krok a dát tam jiný dílek než tam je. Toho, že tam dá zase ten samý dílek se bát nemusíte. Pak už tam třeba nějaký dílek pasovat bude. Tenhle problém už jsem vyřešil.

Jo a promiňte, že píšu tak pozdě.

Prostě potřebuju, aby mi fungovala ta funkce GoTo Line1.

nahlásit spamnahlásit spam -2 / 2 odpovědětodpovědět

Diskuse: Funkce a procedury

Dobrý den,

ve svém programu pro rozvrhování zakázek používám různá pravidla pro jejich výběr a tak bohužel nemohu psát "vše do jednoho" a musím použít funkce. Mohl by mi někdo prosím poradit kde dělám chybu a jak to napravit?

Private Function Selectjob(ByVal pole_E() As Double) as Integer
        Dim Find_s_End_time As Double = 999999
        Dim Selected_Job As Integer
        For i As Integer = 0 To Format_R
            If pole_E(i) < Find_s_End_time And pole_E(i) > 0 Then
                Find_s_End_time = pole_E(i)
                Selected_Job = i
            End If
        Next i
        Return Selected_Job
    End Function

prosím nepodivujte se nad nastavením Find_ .. a pole_E(i) > 0 pramení to z nastavení datové struktury a nastavení pole_E(i) na -1 když je operace odvedena.

Potřebuji aby funkce Selectjob načetla pole_E(i) od jinud a našla i-tý prvek který má nejmenší procesní čas a "odeslala ho zpět". V programu se pak pokouším načíst tuto vybranou operaci (job)

i = Selectjob(Selected_Job)

            Selected_operation(0) = pole_A(i)
            Selected_operation(1) = pole_M(i)
            Selected_operation(2) = pole_P(i)
            Selected_operation(3) = pole_E(i)

Kde s tím pracuji dále.

V kostech cítím, že to nedělám dobře i vzhledem k chybové hlášce

Value of type 'Integer' cannot be converted to '1-dimensional array of Double'.- vztažené na i = Selectjob(Selected_Job)

Přitom (i) a (Selected_job) jsou integer.

Mohl by mi někdo prosím poradit co dělám špatně ? S VB 2005 pracuji teprve třetí týden a funkce jako takové mi dělají v programování obrovské problémy.

Předem děkuji za odpověď

nahlásit spamnahlásit spam -3 / 3 odpovědětodpovědět

Omlouvám se ale už jsem přišel na chybu kterou jsem dělal. Řešení bylo.

funkce je nyní

Private Function Selectjob() As Integer
        Dim zFind_s_End_time As Double = 999
        Dim zSelected_Job As Integer
        For i As Integer = 0 To Format_R
            If pole_E(i) < zFind_s_End_time And pole_E(i) > 0 Then
                zFind_s_End_time = pole_E(i)
                zSelected_Job = i
            End If
        Next i
        Return zSelected_Job
    End Function

a volání

  Sel_i = Selectjob()

            Selected_operation(0) = pole_A(Sel_i)
            Selected_operation(1) = pole_M(Sel_i)
            Selected_operation(2) = pole_P(Sel_i)
            Selected_operation(3) = pole_E(Sel_i)

Nyní vypadá, že vše funguje jak má.

nahlásit spamnahlásit spam -4 / 4 odpovědětodpovědět

Diskuse: Funkce a procedury

Chválim hezky psany serial. Je to psano pekne srozumitelne. Ne jako nektere knihy, kde ma autor 5 titulu pred jmenem a 2 za nim a jednoduchou vec vysvetluje, ze by to nikdo nepochopil. Uz se tesim na dalsi dil.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Vaše myšlenka je bezesporu zajímavá a jistě v určitých situacích platí, avšak znám také mnoho lidí, kteří dovedou psát kvalitní články a mají titulů, že neví, co s nimi. Ale každopádně děkuji za pochvalu.

nahlásit spamnahlásit spam -2 / 2 odpovědětodpovědět

Diskuse: Funkce a procedury

A poklona za rychlost reakce na příspěvek!

nahlásit spamnahlásit spam -3 / 3 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback