Avatar billede jolaur Nybegynder
19. marts 2008 - 03:24 Der er 18 kommentarer

Sortering af "pakker" efter fast algoritme

Hej, Er der nogen, som kan hjælpe mig med følgende problem ?

Jeg skal have sorteret en række tal i "pakker" af 36 - 44 stk. i hver pakke.

De tal der skal sorteres, bliver behandlet efter en fast algoritme.

Alle tal bliver delt med 8, indtil tallet er under 16, derefter deles det resterende tal (under 16) med 2.

Dvs. at feks. tallet 90, deles med 8 ti gange og de resterende 10, deles derefter med 2. Dvs. 5 og 5

Eksempel: 90 ==> 8-8-8-8-8-8-8-8-8-8-5-5

Er tallet istedet 91, vil det se ud som følgende:

Eksempel: 91 ==> 8-8-8-8-8-8-8-8-8-8-6-5

Tal under 16, bliver behandlet som følger:

16 ==> 8-8
15 ==> 8-7
14 ==> 7-7
13 ==> 7-6
12 ==> 6-6
11 ==> 6-5
10 ==> 5-5
9 ==>  5-4
8 ==>  8
7 ==>  7
6 ==>  6
5 ==>  5
4 ==>  4
3 ==>  3
2 ==>  2
1 ==>  1

Når alle "mellemregningerne" er lavet, skal tallene lægges sammen i "pakker" af 36 - 44 stk. i hver pakke

Et eksempel kunne være som følgende:

Jeg har følgende tal:

24
32
45
29
7
11
83

De bliver behandlet som således:

24 ==> 8-8-8
32 ==> 8-8-8-8
45 ==> 8-8-8-8-7-6
29 ==> 8-8-7-6
7  ==> 7
11 ==> 6-5
83 ==> 8-8-8-8-8-8-8-8-8-6-5

Derefter lægges tallene sammen i "pakker" af 36-44 stk.

8-8-8-8-8  ==> 40
8-8-8-8-8  ==> 40
8-7-6-8-8  ==> 37
7-6-7-6-5-8 ==> 39
8-8-8-8-8  ==> 40
8-8-8-6-5  ==> 35

Læg mærke til at den sidste "pakke" indeholder den rest, der er tilbage, og kan altså godt falde uden for intervallet på 36-44 stk.

Jeg vil mene at det skulle være muligt at oprette et regneark, hvor man ved indtastning af tallene, automatisk fik de såkaldte pakker "spyttet" ud i den rigtige rækkefølge.

Håber der er en venlig sjæl, som kan hjælpe.

På forhånd tak.

Mvh John
Avatar billede jlemming Nybegynder
19. marts 2008 - 07:35 #1
Jeg har et svar om ca. ½ time :o)
Avatar billede jlemming Nybegynder
19. marts 2008 - 09:59 #2
noget a' la' dette?

Dine tal skal stå i kolonne a fra række 2

Sub sortere()
Set fraark = Sheets("sheet1")


lastrow = fraark.Range("A65536").End(xlUp).Row

rt = 2
startkolonne = 3
startrakke = 2

For r = startrakke To lastrow  'slet tidligere
    fraark.Range(Cells(r, startkolonne), Cells(r, startkolonne + 30)).ClearContents
Next r

For r = startrakke To lastrow
    tal = fraark.Cells(r, 1)
    tal2 = tal
    t = 0
    While tal2 > 16
            fraark.Cells(r, startkolonne + t) = 8
            tal2 = tal2 - 8
            t = t + 1
    Wend
    If tal2 >= 8 Then
            fraark.Cells(r, startkolonne + t) = RoundUp(tal2 / 2)
            t = t + 1
            fraark.Cells(r, startkolonne + t) = RoundD(tal2 / 2)
            t = t + 1
    Else
        fraark.Cells(r, startkolonne + t) = tal2
    End If
Next r

slutrakke = t
c = 0
Sum = 0
r = startrakke
For r = startrakke To slutrakke 'find den sidste kolonne
    c = fraark.Cells(r, startkolonne).SpecialCells(xlLastCell).Column
    If c > c2 Then c2 = c
Next r
c = 0
r = startrakke

While r < slutrakke + 1
    If fraark.Cells(r, startkolonne + c) > 0 Then
        Sum = fraark.Cells(r, startkolonne + c) + Sum
        c = c + 1
        If Sum >= 36 Then
            fraark.Cells(r, c2 + 1).Value = Sum
            Sum = 0
        End If
    Else
        c = 0
        r = r + 1
    End If
Wend
fraark.Cells(r, c2 + 1).Value = Sum
End Sub
Avatar billede jlemming Nybegynder
19. marts 2008 - 11:34 #3
hov! havde glemt sub funktioner.

Har også rettet lidt

Sub sortere()
Set fraark = Sheets("sheet1")


lastrow = fraark.Range("A65536").End(xlUp).Row

rt = 2
startkolonne = 3
startrakke = 2

For r = startrakke - 1 To lastrow + 1 'slet tidligere
    fraark.Range(Cells(r, startkolonne), Cells(r, startkolonne + 30)).ClearContents
Next r

fraark.Cells(startrakke - 1, startkolonne) = "Mellemregningerne"
For r = startrakke To lastrow
    tal = fraark.Cells(r, 1)
    t = 0
    While tal > 16
            fraark.Cells(r, startkolonne + t) = 8
            tal = tal - 8
            t = t + 1
    Wend
    If tal >= 8 Then
            fraark.Cells(r, startkolonne + t) = RoundUp(tal / 2)
            t = t + 1
            fraark.Cells(r, startkolonne + t) = RoundD(tal / 2)
            t = t + 1
    Else
        fraark.Cells(r, startkolonne + t) = tal
    End If
Next r

c = 0
Sum = 0
r = startrakke
For r = startrakke To lastrow 'find den sidste kolonne
    lastcol = fraark.Range("IV5").End(xlToLeft).Column
    If lastcol > c2 Then c2 = lastcol
Next r

fraark.Cells(startrakke - 1, c2 + 2) = "Pakker"
r = startrakke
While r < lastrow + 1
    If fraark.Cells(r, startkolonne + c) > 0 Then
        Sum = fraark.Cells(r, startkolonne + c) + Sum
        c = c + 1
        If Sum >= 36 Then
            fraark.Cells(r, c2 + 2).Value = Sum
            Sum = 0
        End If
    Else
        c = 0
        r = r + 1
    End If
Wend
fraark.Cells(r, c2 + 2).Value = Sum    'sæt rest
End Sub

Private Function RoundUp(v As Single) As Single
'runder af til heltal
    RoundUp = Round(v)
If Round(v) < v Then
    RoundUp = Round(v) + 1
Else
End If
End Function
Private Function RoundD(v As Single) As Single
'runder ned til heltal
Dim t As Integer
t = v
If t > v Then
    RoundD = t - 1
Else
    RoundD = t
End If
End Function
Avatar billede jolaur Nybegynder
19. marts 2008 - 21:18 #4
Hej jlemming

Tak for dit forslag, kan du evt. guide mig med indtastningen af det ovenstående i Excel, da mit kendskab til regneark, begrænser sig til forholdsvis simple funktioner, så er jeg kommet lidt på dybt vand her.

Hvor skal al den kode indtastes ??

På forhånd tak for hjælpen, og tak for det fine arbejde indtil videre, jeg ser frem til at afprøve resultatet. ;-)

Mvh John
Avatar billede jlemming Nybegynder
19. marts 2008 - 21:40 #5
start med et tomt til at teste med:

-højre klik på ark navn i nedeste venstre hjørne, vælg vis program kode

-Der skulle nu dukke et tomt vindue op, med navnet ark1 (code), klister kode ind.

-Den 2. linie i kode skal evt. ændres afhængig om du kører dansk eller engelsk: Set fraark = Sheets("ark1"), ark1 eller sheet1.

-gå tilbage til excel vinduet
- indtast værdier i kolonne A
- tryk "alt"+ "F8"
- afspil den marko der hedder sortere.

- Så skulle du gerne have dine data !! :o)
Avatar billede jlemming Nybegynder
19. marts 2008 - 21:56 #6
Hov, der er desværre en fejl mere.

Du skal skifte dette afsnit ud
(ellers går det galt ved de store tal)

c = 0
Sum = 0
r = startrakke
c2 = 0
For r = startrakke To lastrow 'find den sidste kolonne
    lastcol = fraark.Cells(r, 256).End(xlToLeft).Column
    If lastcol > c2 Then c2 = lastcol
Next r
Avatar billede jolaur Nybegynder
20. marts 2008 - 04:21 #7
Hej igen.

Det begynder at ligne noget, men der er stadig nogle småting, som ikke helt fungerer optimalt, når jeg prøver.

Er det muligt, at resultatet i pakkerne, kan ligge så tæt på 40 som muligt, da feks. 37 og 4 bliver returneret som 37 og 4, i stedet for som 41, hvilket ville være mere optimalt. ?

Ved høje tal (over 76) , går det galt ved sammentælningen i pakker og alle tal bliver ikke talt sammen.

Tallet 8 blev delt med 2  og blev til 4 og 4, det skal returneres som 8, jeg har rettet fra 8 til 9 i koden

Wend
    If tal >= 9 Then


Ved indtastning af foreksempel 8 forskellige tal og kørsel af makroen, for derefter at rette til feks. kun 5 tal og så køre makroen igen, er der flere af de ”gamle” mellemregninger, som bliver ”hængende” i regnearket.

Det er tæt på at være helt perfekt, men der mangler lige det sidste i at fungere optimalt.

Mvh John
Avatar billede jlemming Nybegynder
24. marts 2008 - 21:25 #8
Ja, Det er noget hø, det jeg har fået lavet her!

Jeg skal lige høre hvor store tal, du kommer til at bruge?
og skal du bruge mellemregningerne til noget.

Jeg skal hvis skrive koden helt om, så må jeg hellere gøre det korrekt med det samme.

Undskyld ventetiden, men har været på ferie
Avatar billede jolaur Nybegynder
25. marts 2008 - 02:46 #9
Hej jlemming

Håber du har haft en god ferie.

Ang. størrelsen af de tal som jeg kan forvente at skulle bruge, kan der godt forekomme enkelttal, som nærmer sig 1500.

Mellemregningerne er ikke noget must. De ville være rare at have, men kan godt undværes. Jeg tænkte på om man evt. ikke kunne returnere dem på et seperat ark.?

Ang. stakkene, så vil det mest optimale være, hvis værdien kunne ligge så tæt på 40 stk. som muligt, og samtidig indenfor den fastsatte difference på de 36-44 stk.

Er det muligt, at returnere værdierne af stakkene i en form for tabel, da der i ekstreme tilfælde, kan være helt op til 50-60 stakke. Så var det lidt nemmere at overskue hvis det var listet i en tabel, men det er heller ikke noget must.

Måske lidt ala sådan her

40 40 40 40 40 40 38 40 41 40
39 44 38 40 40 40 40 40 40 40
44 40 40 40 40 40 40 38 40
40 39 44 38 40 40 40 40 40
40 40 40 40 40 40 40 38 40



Mvh John
Avatar billede jlemming Nybegynder
26. marts 2008 - 21:13 #10
så er det hvis lykkes,
Prøv det, skulle kunne klare 500 pakker

Sub sortere()
Set fraark = Sheets("ark1")

lastrow = ActiveSheet.UsedRange.Row ' start række af brugt område
lastrow = ActiveSheet.UsedRange.Rows.Count ' antal brugt rækker
   
startkolonne = 3
startrakke = 2  ' række data starter i

fraark.Range(Cells(startrakke - 1, startkolonne), Cells(fraark.UsedRange.Rows.Count + fraark.UsedRange.Row - 1, fraark.UsedRange.Columns.Count + startkolonne)).Delete

lastrow = fraark.Range("A65536").End(xlUp).Row

fraark.Cells(startrakke - 1, startkolonne) = "Antal 8'er:"
fraark.Cells(startrakke - 1, startkolonne + 1) = "Rest 1"
fraark.Cells(startrakke - 1, startkolonne + 2) = "Rest 2"
fraark.Cells(startrakke - 1, startkolonne + 4) = "Kontrolsum"

ottere = 0
For r = startrakke To lastrow
    tal = fraark.Cells(r, 1)
    t = 0
    While tal > 16
            ottere = ottere + 1
            tal = tal - 8
            t = t + 1
    Wend
    If tal >= 9 Then    'for tal mellem 9-16
            fraark.Cells(r, startkolonne) = ottere
            fraark.Cells(r, startkolonne + 1) = RoundUp(tal / 2)
            t = t + 1
            fraark.Cells(r, startkolonne + 2) = RoundD(tal / 2)
            t = t + 1
    Else                ' tal < 9
        fraark.Cells(r, startkolonne + 1) = tal
        fraark.Cells(r, startkolonne + 2) = 0
    End If
    ottere = 0
    fraark.Cells(r, startkolonne + 4) = fraark.Cells(r, startkolonne) * 8 + fraark.Cells(r, startkolonne + 1) + fraark.Cells(r, startkolonne + 2)
Next r

Sum = 0
t = 0
r = startrakke
pnr = 0        ' pakker nr
Sum = 0
Dim pakker(500) As Integer
While r < lastrow + 1
    ottere = fraark.Cells(r, startkolonne) 'hent antal ottere
igen:
    While ottere > 0 And Sum < 36
        ottere = ottere - 1
        Sum = Sum + 8
    Wend
    If ottere > 0 Then
        pakker(pnr) = Sum
        pnr = pnr + 1
        Sum = 0
        GoTo igen
    Else
        If Sum + fraark.Cells(r, startkolonne + 1) < 44 Then    'hent rest 1
            Sum = Sum + fraark.Cells(r, startkolonne + 1)
            If Sum + fraark.Cells(r, startkolonne + 2) < 44 Then    'hent rest 2
                Sum = Sum + fraark.Cells(r, startkolonne + 2)
            Else
                pakker(pnr) = Sum
                pnr = pnr + 1
                Sum = fraark.Cells(r, startkolonne + 2) ' start med rest 2
            End If
        Else
            pakker(pnr) = Sum
            pnr = pnr + 1
            Sum = fraark.Cells(r, startkolonne + 1) ' start med rest 1
        End If
    End If
    r = r + 1
Wend
pakker(pnr) = Sum  ' rest

' udskriv pakker
rpakker = 5    ' startrække efter indtastet værdier
cantal = 10    ' antal kolonne for pakker
rc = 0          'række count for pakker
cc = 0          ' kolonne count for pakker

fraark.Cells(lastrow + rpakker, startkolonne).Value = "Pakker"
For t = 0 To pnr
    fraark.Cells(lastrow + rpakker + 1 + rc, startkolonne + cc).Value = pakker(t)
    cc = cc + 1
    If cc > cantal Then
        cc = 0
        rc = rc + 1
    End If
Next t
End Sub

Private Function RoundUp(v As Single) As Single
'runder af til heltal
    RoundUp = Round(v)
If Round(v) < v Then
    RoundUp = Round(v) + 1
Else
End If
End Function
Private Function RoundD(v As Single) As Single
'runder ned til heltal
Dim t As Integer
t = v
If t > v Then
    RoundD = t - 1
Else
    RoundD = t
End If
End Function
Avatar billede jolaur Nybegynder
28. marts 2008 - 02:53 #11
Hej igen.

Nu har jeg været igennem en del test, med forskellige tal, og der er et eller andet, som ikke helt fungerer når der bliver talt sammen til pakker.

Som jeg ser det, så er alle mellemregningerne iorden, men når det bliver lagt sammen, er der et eller andet som går skævt.

En simpel test, prøv at skrive 88 i a2 og 88 i a3.

Det skulle gerne returnere 176 ialt, men det returnerer kun 168

Ligeledes, har jeg prøvet med disse tal

4
3
22
15
58
51
31
39
176
132
58
8
78
8
13
20
3
16
58

Summen af disse tal er 793, men når man regner summen ud af de pakker der bliver genereret, så giver det kun 781.

Er det evt. muligt, at liste pakkerne lodret, med 10 pakker i hver kollone. ?

Mvh John
Avatar billede jlemming Nybegynder
28. marts 2008 - 08:25 #12
Vi prøver igen.

Synes ellers jeg havde prøvet med mange forskellige tal. :o)

Listere også pakker lodret

Sub sortere()
Set fraark = Sheets("sheet1")

lastrow = ActiveSheet.UsedRange.Row ' start række af brugt område
lastrow = ActiveSheet.UsedRange.Rows.Count ' antal brugt rækker
   
startkolonne = 3
startrakke = 2  ' række data starter i

fraark.Range(Cells(startrakke - 1, startkolonne), Cells(fraark.UsedRange.Rows.Count + fraark.UsedRange.Row - 1, fraark.UsedRange.Columns.Count + startkolonne)).Delete

lastrow = fraark.Range("A65536").End(xlUp).Row

fraark.Cells(startrakke - 1, startkolonne) = "Antal 8'er:"
fraark.Cells(startrakke - 1, startkolonne + 1) = "Rest 1"
fraark.Cells(startrakke - 1, startkolonne + 2) = "Rest 2"
fraark.Cells(startrakke - 1, startkolonne + 4) = "Kontrolsum"

ottere = 0
For r = startrakke To lastrow
    tal = fraark.Cells(r, 1)
    t = 0
    While tal > 16
            ottere = ottere + 1
            tal = tal - 8
            t = t + 1
    Wend
    If tal >= 9 Then    'for tal mellem 9-16
            fraark.Cells(r, startkolonne) = ottere
            fraark.Cells(r, startkolonne + 1) = RoundUp(tal / 2)
            t = t + 1
            fraark.Cells(r, startkolonne + 2) = RoundD(tal / 2)
            t = t + 1
    Else                ' tal < 9
        fraark.Cells(r, startkolonne + 1) = tal
        fraark.Cells(r, startkolonne + 2) = 0
    End If
    ottere = 0
    fraark.Cells(r, startkolonne + 4) = fraark.Cells(r, startkolonne) * 8 + fraark.Cells(r, startkolonne + 1) + fraark.Cells(r, startkolonne + 2)
Next r

Sum = 0
t = 0
r = startrakke
pnr = 0        ' pakker nr
Sum = 0
Dim pakker(500) As Integer
While r < lastrow + 1
    ottere = fraark.Cells(r, startkolonne) 'hent antal ottere
igen:
    While ottere > 0 And Sum < 36
        ottere = ottere - 1
        Sum = Sum + 8
    Wend
    If ottere > 0 Then
        pakker(pnr) = Sum
        pnr = pnr + 1
        Sum = 0
        GoTo igen
    Else
        If Sum + fraark.Cells(r, startkolonne + 1) < 44 Then    'hent rest 1
            Sum = Sum + fraark.Cells(r, startkolonne + 1)
            If Sum + fraark.Cells(r, startkolonne + 2) < 44 Then    'hent rest 2
                Sum = Sum + fraark.Cells(r, startkolonne + 2)
            Else
                pakker(pnr) = Sum
                pnr = pnr + 1
                Sum = fraark.Cells(r, startkolonne + 2) ' start med rest 2
            End If
        Else
            pakker(pnr) = Sum
            pnr = pnr + 1
            Sum = fraark.Cells(r, startkolonne + 1) ' start med rest 1
            Sum = fraark.Cells(r, startkolonne + 2) + Sum ' forsæt med rest 2

        End If
    End If
    r = r + 1
Wend
pakker(pnr) = Sum  ' rest

' udskriv pakker
rpakker = 5    ' startrække efter indtastet værdier
rantal = 10    ' antal rækker for pakker
rc = 0          'række count for pakker
cc = 0          ' kolonne count for pakker

fraark.Cells(lastrow + rpakker, startkolonne).Value = "Pakker"
For t = 0 To pnr
    fraark.Cells(lastrow + rpakker + 1 + rc, startkolonne + cc).Value = pakker(t)
    rc = rc + 1
    If rc > rantal Then
        rc = 0
        cc = cc + 1
    End If
Next t
End Sub

Private Function RoundUp(v As Single) As Single
'runder af til heltal
    RoundUp = Round(v)
If Round(v) < v Then
    RoundUp = Round(v) + 1
Else
End If
End Function
Private Function RoundD(v As Single) As Single
'runder ned til heltal
Dim t As Integer
t = v
If t > v Then
    RoundD = t - 1
Else
    RoundD = t
End If
End Function
Avatar billede jolaur Nybegynder
28. marts 2008 - 13:29 #13
Hej igen

Når jeg kopierer den nye kode ind, så får jeg bare en fejlmeddelelse "Subscript out of range"

Hilsen John
Avatar billede jlemming Nybegynder
28. marts 2008 - 14:24 #14
Det er nok fordi, du lige skal ændre den 2. linie, med ark navnet fra sheet1 til ark1, Det er fordi bruger 2 forskellige maskiner dansk og engelsk
Avatar billede jolaur Nybegynder
29. marts 2008 - 19:48 #15
Ja, selvfølgelig, den havde jeg ikke lige set.

Nu ser det ud til at det fungerer helt perfekt, efter de oplysninger, som jeg har givet.

Flot arbejde.

Der er bare lige et par småting, som, hvis det er muligt at kontrolere, ville gøre det helt perfekt.

Jeg har desværre ikke fået oplyst at det mest optimale for mig, ville være at hvis de returnerede pakkers værdi kan ligge så tæt på 40 som muligt, så vil det være helt perfekt.

Når jeg foreksempel bruger følgende tal

40
1
1
2
2
2
40

Returnerer den pakker som følgende
42
38
8

Det ville være mest optimalt for mig, hvis der returneres pakker som følgende
40
40
8

Jeg ser frem til at høre fra dig, og nu er vi vist ved at være klar til et svar, så der kan komme nogle point din vej.

Tusind tak for hjælpen indtil nu.

Mvh John
Avatar billede jolaur Nybegynder
04. april 2008 - 11:25 #16
Hej igen

Ville lige høre, om du har haft tid til at kigge på min sidste post.

Mvh John
Avatar billede jlemming Nybegynder
09. april 2008 - 08:56 #17
Hej John

Undskyld mit fravær, chefen mente lige pludslig at jeg skulle lave en hel masse. !!!

Jeg har lidt problemer med algoritmen til det sidste. Håber jeg får tid hen over weekenden
Avatar billede jolaur Nybegynder
10. april 2008 - 00:44 #18
Hej jlemming

Det er helt iorden. ;-)

Mvh John
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Excel kurser for alle niveauer og behov – find det kursus, der passer til dig

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester