Fórum pro uživatele kancelářského balíku OpenOffice | LibreOffice
 

#1 1. 10. 2011 20:06:19

neutr
Člen
Registrace: 8. 3. 2007
Příspěvků: 3,435

Makra v Calcu VYŘEŠENO

Zdravím. Mám určitý problém s makrem. Používán několik způsobů pro stejný účel. Funkce If mi při prvním způsobu (Main1) funguje, ale je pomalejší a i méně přehledná. To druhé makro (Main2) zase nečte funkci If. Jde sice o jiné deklarace, ale ten druhý způsob (zřejmě z Excelu, nebo jiného Basicu - už nevím jak jsem na to přišel) Funguje v jiném makru přímo skvěle. Ty první makra jsou řídící pro makro "Vykonny" a to funguje bezvadně přestože je deklarována druhým stylem. Chtěl jsem to dát jako návod a s touhle ptákovinou si nevím rady - ani ryba ani rak. Zajímá mne, jestli někdo ví proč to je. Ukázka Main1, Main2, a Výkonny.

Sub Main1
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

Dim H2
Sheet = thisComponent.Sheets(0)
H2 = Sheet.getCellRangeByName("H2")
Dim H6
H6 = Sheet.getCellRangeByName("H6")

For iCount = 1 To 10000

IF H2.Value = H6.Value Then
Print "Překopíruj a smaž výsledky"
Stop REM (Exit Sub)
End If

Call Vykonny

Next iCount

End Sub

_____________________________________________________

Sub Main2
oDoc = ThisComponent
    oSheets = oDoc.Sheets
    oSheet = oSheets.getByIndex(0)
H2 = oSheet.getCellbyPosition(7,1).Value
H6 = oSheet.getCellbyPosition(7,5).Value

For iCount = 1 To 10000

REM tahle funkce nefunguje PROČ?
IF H2 = H6 Then
Print "Překopíruj a smaž výsledky"
Stop REM (Exit Sub)
End If

Call Vykonny

Next iCount

End Sub

_______________________________________________________


Sub Vykonny
oDoc = ThisComponent
    oSheets = oDoc.Sheets
    oSheet = oSheets.getByIndex(0)
A1 = oSheet.getCellbyPosition(0,0).Value
B1 = oSheet.getCellbyPosition(1,0).Value
C1 = oSheet.getCellbyPosition(2,0).Value
D1 = oSheet.getCellbyPosition(3,0).Value
E1 = oSheet.getCellbyPosition(4,0).Value

A2 = oSheet.getCellbyPosition(0,1).Value
B2 = oSheet.getCellbyPosition(1,1).Value
C2 = oSheet.getCellbyPosition(2,1).Value
D2 = oSheet.getCellbyPosition(3,1).Value
E2 = oSheet.getCellbyPosition(4,1).Value

REM Funkce vylučující zápis variace s opakováním prvků
REM bez této funkce generátor generuje variace s opakováním
IF A1 <> B1 AND A1 <> C1 AND A1 <> D1 AND A1 <> E1 AND B1 <> C1 AND B1 <> D1 AND B1 <> E1 And C1 <> D1 AND C1 <> E1 And D1 <> E1 Then
Call krok_0 REM Rídí zápis do registru výsledků 
End IF

REM Vlastní krok podmínečné iterace
IF A1 = A2 AND B1 = B2 AND C1 = C2 And D1 = D2 And E1 = E2 Then
Exit Sub
Else IF A1 < A2 AND B1 = B2 AND C1 = C2 And D1 = D2 And E1 = E2 Then
oSheet(0).getCellByPosition(0,0).SetFormula(A1+1)
oSheet(0).getCellByPosition(1,0).SetFormula(1)
oSheet(0).getCellByPosition(2,0).SetFormula(1)
oSheet(0).getCellByPosition(3,0).SetFormula(1)
oSheet(0).getCellByPosition(4,0).SetFormula(1)
Else IF B1 < B2 AND C1 = C2 And D1 = D2 And E1 = E2 Then
oSheet(0).getCellByPosition(1,0).SetFormula(B1+1)
oSheet(0).getCellByPosition(2,0).SetFormula(1)
oSheet(0).getCellByPosition(3,0).SetFormula(1)
oSheet(0).getCellByPosition(4,0).SetFormula(1)
Else IF C1 < C2 And D1 = D2 And E1 = E2 Then
oSheet(0).getCellByPosition(2,0).SetFormula(C1+1)
oSheet(0).getCellByPosition(3,0).SetFormula(1)
oSheet(0).getCellByPosition(4,0).SetFormula(1)
Else IF D1 < D2 And E1 = E2 Then
oSheet(0).getCellByPosition(3,0).SetFormula(D1+1)
oSheet(0).getCellByPosition(4,0).SetFormula(1)
Else IF E1 < E2 Then
oSheet(0).getCellByPosition(4,0).SetFormula(E1+1)
End IF
End IF
End IF
End IF
End IF
End IF

End Sub 

Poznámka - toto makro je plně funkčním generátorem - 1 krok libovolné variace 5. třídy bez opakování z libovolného základu. Po úpravě (ta je poznamenána) můžeme generovat variace 5. třídy libovolného základu s opakováním. Je však třeba nastavit pracovní prostředí a to se dělá "velkým" makrem. Zájemcům to pošlu, ale chtěl bych to dát do návodů. Děkuji za náměty
Petr

Editoval neutr (8. 10. 2011 07:03:02)


Moje e-mailová adresa
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte orientaci při vyhledávání řešení JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#2 1. 10. 2011 20:54:23

sedlacekdan
Moderátor
Místo Nehvizdy
Registrace: 21. 6. 2010
Příspěvků: 617

Re: Makra v Calcu VYŘEŠENO

Sub Main2


oDoc = ThisComponent
oSheets = oDoc.Sheets
oSheet = oSheets.getByIndex(0)


H2 = oSheet.getCellbyPosition(7,1).value
H6 = oSheet.getCellbyPosition(7,5).value


if H2 = H6 Then
Print "Překopíruj a smaž výsledky"
exit sub
end If


For iCount = 1 To 10000
Vykonny
next iCount


End Sub 

Ten test shodnosti bych vyhodil mimo cyklus, zbytečně se 10000 testuje hodnota, která je známa hned po prvním testu.


Co máte za hodnoty v H2 a H6, při číselných hodnotách mi If funguje bez problémů. Pokud chcete testovat i text, změňte z .value na .string.


Obě Vaše varianty Main1 i Main2 jsou na výkon prakticky stejně rychlé. Částečné urychlení může přinést právě přesun if mimo cyklus.
Nejdéle ovšem trvá v cyklu 10000-krát volané makro Vykonny. Konečný výsledek je ten, že pokud nejsou čísla od sebe dostatečně vzdáleny dojde k vyrovnání hodnot mezi buňkami A1 a 2, B1 a 2....


Toto ale asi nebyl účel makra....


;o)


Linux Mint 16 Petra - Apache OpenOffice 4.0.1
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte tak orientaci na fóru při vyhledávání řešení problémů
JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#3 2. 10. 2011 08:29:48

neutr
Člen
Registrace: 8. 3. 2007
Příspěvků: 3,435

Re: Makra v Calcu VYŘEŠENO

Ano máš pravdu. Test H2 ku H6 je poměr skutečného stavu položek registru výsledků daný vzorcem COUNTA(J2:J1000000). Potřebuji, aby makro zastavilo například na počtu 100 tisíc, nebo tolik, kolik comp uveze. Cyklus For .. Next sice dělá zadaný počet, ale zapíše jen málo (nakro Vykonny vybírá jen variace bez opakování, přičemž generátor dává variace s opakováním). Takže například po 1000 cyklech mám jen 260 zapsaných výsledků. Navíc For ..Next užívám ve spojení se záznamem času - zapíšu čas spuštění a skončení při určitém počtu cyklů a vzniklých výsledků. Následně For..Next nahrazuji samozřejmě jiným cyklem - nejčastěji Do..Loop, a pak už to visí jen na přednastaveném počtu výsledků. Znám při tom i přibližný čas generování - takže jdu třeba nakoupit a nechám ho makat.
Další věc je, že jsem zkoušel zadeklarovat místo value "string" ale také mi to nechodilo. Ale pro jistotu se podívám ještě jednou. H2 je skutečně jen číslo (nastavená limita výsledků), ale H6 je vzorec - to bylo úprvní co jsem zkoušel. Je možné, že jsem zazmatkoval někde jinde. Ale děkuju za snahu i námět.


Moje e-mailová adresa
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte orientaci při vyhledávání řešení JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#4 2. 10. 2011 09:01:42

neutr
Člen
Registrace: 8. 3. 2007
Příspěvků: 3,435

Re: Makra v Calcu VYŘEŠENO

Tak jsem to udělal znovu a nic. "String" se mi vybarví modře. "Str" to nezná.


Moje e-mailová adresa
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte orientaci při vyhledávání řešení JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#5 2. 10. 2011 12:13:52

sedlacekdan
Moderátor
Místo Nehvizdy
Registrace: 21. 6. 2010
Příspěvků: 617

Re: Makra v Calcu VYŘEŠENO

OK změňte text if na:

if val(H2) = val(H6) Then

val(hodnota) změní jakoukoliv hodnotu na její číselné vyjádření, text jako 0, výsledek vzorce jako číslo, čísla zůstávají.


z makra Main2 vyhoďte cyklus (for iCount)

Makro Vykonny bych změnil takto:

Sub Vykonny
oDoc = ThisComponent
    oSheets = oDoc.Sheets
    oSheet = oSheets.getByIndex(0)


A1 = oSheet.getCellbyPosition(0,0)
B1 = oSheet.getCellbyPosition(1,0)
C1 = oSheet.getCellbyPosition(2,0)
D1 = oSheet.getCellbyPosition(3,0)
E1 = oSheet.getCellbyPosition(4,0)


A2 = oSheet.getCellbyPosition(0,1)
B2 = oSheet.getCellbyPosition(1,1)
C2 = oSheet.getCellbyPosition(2,1)
D2 = oSheet.getCellbyPosition(3,1)
E2 = oSheet.getCellbyPosition(4,1)


[b]for iCount = 1 to 10000[/b]


REM Funkce vylučující zápis variace s opakováním prvků
REM bez této funkce generátor generuje variace s opakováním
IF A1.value <> B1.value AND A1.value <> C1.value AND A1.value <> D1.value AND A1.value <> E1.value AND B1.value <> C1.value AND B1.value <> D1.value AND B1.value <> E1.value And C1.value <> D1.value AND C1.value <> E1.value And D1.value <> E1.value Then
Call krok_0 REM Rídí zápis do registru výsledků 
[b]exit for[/b]
End IF


REM Vlastní krok podmínečné iterace
IF A1.value = A2.value AND B1.value = B2.value AND C1.value = C2.value And D1.value = D2.value And E1.value = E2.value Then
Exit Sub
ElseIF A1.value < A2.value AND B1.value = B2.value AND C1.value = C2.value And D1.value = D2.value And E1.value = E2.value Then
A1.SetFormula(A1.value+1)
B1.SetFormula(1)
C1.SetFormula(1)
D1.SetFormula(1)
E1.SetFormula(1)


ElseIF B1.value < B2.value AND C1.value = C2.value And D1.value = D2.value And E1.value = E2.value Then
B1.SetFormula(B1.value+1)
C1.SetFormula(1)
D1.SetFormula(1)
E1.SetFormula(1)


ElseIF C1.value < C2.value And D1.value = D2.value And E1.value = E2.value Then
C1.SetFormula(C1.value+1)
D1.SetFormula(1)
E1.SetFormula(1)


ElseIF D1.value < D2.value And E1.value = E2.value Then
D1.SetFormula(D1.value+1)
E1.SetFormula(1)


ElseIF E1.value < E2.value Then
E1.SetFormula(E1.value+1)


EndIF


[b]next iCount[/b]


End Sub 

Cyklus přeneste z prvního makra do makra vykonny  průběh bude rychlejší. makro Main2 ponechte pouze jako spouštěč.


Neměřil jsem to, ale dosud makro dokola definovalo adresu buněk což mi přijde delší, než definovat druh hodnoty (.value).
Nejlepším řešením by bylo makro, které nebude zapisovat průběžný výpočet do buněk, zapíše až jeho výsledek.

;o)


Linux Mint 16 Petra - Apache OpenOffice 4.0.1
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte tak orientaci na fóru při vyhledávání řešení problémů
JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#6 2. 10. 2011 21:49:36

neutr
Člen
Registrace: 8. 3. 2007
Příspěvků: 3,435

Re: Makra v Calcu VYŘEŠENO

Dane pořád to není ono. Prostě jsem zase vyzkoušel všechny obměny a to IF mi podmínku nečte, nezastaví. Makro Vykonny maká perfektně i podle Tvého návodu. Tak jsem zkoušel kombinace deklaracemi bez proměnných - tak jak to máš v makru Vykonny plus val(H2) = val(H6). Zkoušel jsem i H2 = val(H6) s s proměnou v deklaraci H2 a H6 s deklarací i bez deklarace, ale stejně nic. Prošel jsem i možnosti jiného názvu listu, protože tem původní měl jméno textem. Zítra to budu zkoumat znova. Ale děkuji. Možná by bylo lepší, abych Ti poslal kompletní sešit. Mám tam ještě instalační makro pro instalaci pracovního prostředí, do kterého se pak Main pouští. Pak také potřebuješ makro krok_0. Takže emailem bych Ti to mohl poslat? Zatím dík


Moje e-mailová adresa
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte orientaci při vyhledávání řešení JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#7 3. 10. 2011 04:18:19

sedlacekdan
Moderátor
Místo Nehvizdy
Registrace: 21. 6. 2010
Příspěvků: 617

Re: Makra v Calcu VYŘEŠENO

JAK VLOŽIT SOUBOR


Je lepší soubor odkázat do fóra:
1. přece jen je veřejné
2. podobný problém může mít kdokoliv
3. problém řeší více lidí


Samozřejmě pokud obsahuje nějaké údaje, které nemají být veřejné tak mailem.


Popis problému a jeho řešení pak bude zveřejněno


;o)


Linux Mint 16 Petra - Apache OpenOffice 4.0.1
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte tak orientaci na fóru při vyhledávání řešení problémů
JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#8 4. 10. 2011 15:53:42

neutr
Člen
Registrace: 8. 3. 2007
Příspěvků: 3,435

Re: Makra v Calcu VYŘEŠENO

Přišel jsem na příčinu, ale závadu jsem nedokázal odstranit. Je to trochu speciálnější téma, a je potřeba vložit soubor, aby si to mohl zájemce ověřit. Proto otevřu nový příspěvek. Řeknu jen na závěr, že při iteraci vznikne místo čísla text. Stává se to jen v případě, že jde o jiný typ, než Integer a Long Integer (chybu hází nejen vzorce, ale i čísla s desetinným místem. Celá čísla fungují normálně). Zatím to neumím přetypovat, ale zjistil jsem, že jde zřejmě o neduh OOo.


Moje e-mailová adresa
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte orientaci při vyhledávání řešení JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#9 5. 10. 2011 19:27:15

hanus
Člen
Místo Olomouc
Registrace: 29. 11. 2006
Příspěvků: 573
Web

Re: Makra v Calcu VYŘEŠENO

Jak píšete, záleží na zdrojových datech, která z makra porovnáváte - pokud jsou to jen čísla, pak je načítat v makru pomocí .Value, pokud jsou to texty, tak pomocí .String, problém nastává u smíšených dat (čísla, texty, datumy aj.). Doporučená konstrukce Val(.String) také není spásou. Pro zajímavost příklad:
Porovnání hodnot.ods


Při val(string) je nutno pamatovat na to, že Basic potřebuje desetinná čísla s tečkou, nikoli s čárkou (vizte příklady na ř.3 a 4, val("10,0")=100 nikoli 10) a řetězce převádí na nuly (proto se rovnají hodnoty na ř.2 a 7; ale třeba val("12A")=val("12C") ).
makro-porovnani-val.png


Při použití .String v případě čísel ztroskotáte u stejných čísel s různým počtem desetinných míst, vizte ř.3 a 4
makro-porovnani-string.png

Editoval hanus (5. 10. 2011 19:41:50)

Offline

#10 5. 10. 2011 23:44:51

lp.
Člen
Registrace: 24. 9. 2009
Příspěvků: 842

Re: Makra v Calcu VYŘEŠENO

Musím přiznat, že to celé moc nechápu.

Máte problém s porovnávanými hodnotami.
1) Co je v proměných, když dojde k chybě? Existuje přece trasování maker.

2) Nepochopil jsem sice, co makro vlasně dělá, přesto, až na pár výjimek považuji ukládání mezivýsledků činnosti makra v buňkách listu za špatný nápad.

3) Předpokládám, že ten ošklivý text v některé z buněk Hx generuje procedura krok_0, kde je?

4) Pokud jsou vstupní data v listu a některé hodnoty dělají problémy, bylo by možná vhodné je nejprve otestovat.

Offline

#11 6. 10. 2011 06:16:37

j-pastierik
Člen
Registrace: 15. 11. 2004
Příspěvků: 761

Re: Makra v Calcu VYŘEŠENO

to Hanus: najlepšie je urobiť si vlastnú funkciu pre prevod reťazca na číslo, kde prípadné desatinné čiarky zmeníme za bodky a potom testovať rovnosť val(Upravislo(...))

function UpravCislo(sCislo$) as string
 dim sCela$ : sCela="" ' Celá časť čísla
 dim sDesatinna$ : sDesatinna="" ' Desatinná časť čísla
 dim kde%
 
 ' Vyhľadanie desatinnej čiarky alebo bodky
 kde=instr(sCislo,",")
 if kde=0 then kde=instr(sCislo,".")
  
 if kde>0 then ' Je zadaná desatinná čiarka/bodka - reálne číslo
  sCela=left(SCislo,kde-1) ' Celá časť
  kde=len(SCislo)-kde ' Zistenie polohy desatinnej časti. Číslo môže byť zadané napr. "3.", vtedy sa desatinná časť nezisťuje
  if kde>0 then ' Desatinná časť nie je prázdna
   sDesatinna=right(sCislo,kde)
  endif
  UpravCislo=sCela+"."+sDesatinna
 else ' Nie je zadaná desatinná časť - celé číslo
  UpravCislo=SCislo
 endif
end function

Editoval j-pastierik (6. 10. 2011 06:17:16)

Offline

#12 6. 10. 2011 08:55:07

neutr
Člen
Registrace: 8. 3. 2007
Příspěvků: 3,435

Re: Makra v Calcu VYŘEŠENO

Děkuji za náměty bez nadsázky nestorů, či klasiků pánů Pastirika a Hanuse. Půjdu to zkusit. Pro ostatní, kteří úplně nechápou oč jde jsem vytvořil sešit s popisem problematiky a s makry, která problém vykreslují. Je to jednoúčelové, tak tam nehledejte žádný jiný smysl, nežli popis problémů. Jsou tam makra Main_0, Main_1, Main_2, Vzorec1, Vzorec2 a Zápis. Je zde popis testu, který jsem provedl a můžete si jej zopakovat. Spouštíme jednotlivá makra Main, která obsahují odkaz (Call) na makro Vzorec1(2) - to číslo se musí ručně přepsat, když testujeme podle druhého vzorce. Problémy jsou zde popsány dva, i když v důsledku to asi bude jen jediný. Stáhnout se to může z adresy Dotaz wiki.ods


Moje e-mailová adresa
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte orientaci při vyhledávání řešení JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#13 6. 10. 2011 09:33:23

neutr
Člen
Registrace: 8. 3. 2007
Příspěvků: 3,435

Re: Makra v Calcu VYŘEŠENO

Pro Ip: Ne není to makrem krok_0. krok_0 jen zavádí hodnotu mezi výsledky. To co jsem uvedl na začátku platí - jde o vývoj generátorů variací a variací s opakováním. Všechna makra jsou jen ve vývojové verzi - a jsou dislokovaná. Na konci by mělo být jen jedno makro Instalační (instaluje pracovní prostředí podle výběru). Vybrané pracovní prostředí bude obsluhováno jediným makrem, které však bude vždy obsahovat nějakou formu makra krok. To proto, že generátory budou generovat fyzické tvary variací - tedy databáze s mnohdy obrovským počtem řádků, a to i do více listů, které by se měly ukládat nejspíš jako csv. Tyto databáze už mají statickou povahu a budou obsluhovány jinými programy podle volby uživatele. Mimo to bych chtěl ještě postavit generátory, které budou umět posoudit obsah určité databáze - například rozpis loterie, který bude otestován všemi různými kombinacemi ze všech možných C(n,k), nebo generátory výběrů (v podstatě rozpisů). Je toho hodně. Já to dělám poměrně často, ale mojí limitou (a limitou obecně)je výkon HW a SW. Úprava makra je jedinou možností jak zrychlit takovéhle procesy. Funkčních generátorů jsem už postavil skutečně mnoho, ale po testu času jsem zjistil, že potřebuji například desítky pracovních dnů - a makro šlo slušně řečeno "do archivu".


Moje e-mailová adresa
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte orientaci při vyhledávání řešení JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#14 6. 10. 2011 09:42:01

lp.
Člen
Registrace: 24. 9. 2009
Příspěvků: 842

Re: Makra v Calcu VYŘEŠENO

Tak zatím:

makro main_1. Do proměnné D3 a E3 vkládáte objekt (buňku). Tento objekt je propojen s listem a proto D3.Value vrací aktuální hodnotu buňky v listu.

makro main_2. Do proměnné D3 a E3 vkládáte hodnotu buňky před začátkem cyklu. Ta se dále neaktualizuje. Proto podmínka nemůže fungovat.

Offline

#15 6. 10. 2011 10:26:31

neutr
Člen
Registrace: 8. 3. 2007
Příspěvků: 3,435

Re: Makra v Calcu VYŘEŠENO

Pro IP : Zřejmě máš na mysli pořadí Call Vzorec následně Call Zapis. Když to přehodíš, tak je to stejné. Na pořadí nezáleží. V cyklu For je otestována podmínka, která buď zastaví, nebo nezastaví na počtu výsledků. Je jedno jestli nejdříve zapíše hodnotu, a pak v následujícím cyklu vyhodnotí konec, nebo jestli to zastaví hned. Dokonce si myslím, že snadno postavím iteraci a Zápis před podmínku IF a půjde to stejně. Hrálo by to úlohu, když bych startoval jinak, než z prázdného registru. Tam by se mohlo stát, že pokud se provede nejprve Zápis, tak překoná limitu. To by se ale dalo ošetřit operátorem >=. Přepiš si to tak, aby sled příkazů byl shodný jak u Main_1, tak u Main_2 a uvidíš.


Moje e-mailová adresa
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte orientaci při vyhledávání řešení JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#16 6. 10. 2011 10:37:41

lp.
Člen
Registrace: 24. 9. 2009
Příspěvků: 842

Re: Makra v Calcu VYŘEŠENO

Pokud Vás limituje doba výpočtu, určitě převeďte výpočet do paměti. ¨Místo do listu při výpočtu ukládejte data do pole v paměti a po dokončení výpočtu nebo naplnění pole *celé* pole vložte do listu (jeden příkaz, bloková operace, je to mnohonásobně rychlejší než opakované čtení a zápis do jednotlivých buněk. Zkoušel jsem bez problémů pole se 100000 řádky a 10 sloupci.

variace = sheet.getCellRangeByName("A1:E50000").getDataArray  
' dostaneme vektor vektorů nebo lépe vektor řádků

' příklad na jednotlivé prvky

' nějaká operace 
cyklus :
   ' adresovat mus9me takto
   variace(rarek)(sloupec) = hodnota

   ' nebo takto
   variace(rarek) = radek_hodnot
next i

' a uložíme zpět
sheet.getCellRangeByName("A2:E50000").setDataArray(variace)

Druhá možnost je optimalizace výpočtu - např. globální řídící proměnné, optimalizace volání procedur, ...

Editoval lp. (6. 10. 2011 10:48:59)

Offline

#17 6. 10. 2011 10:57:02

neutr
Člen
Registrace: 8. 3. 2007
Příspěvků: 3,435

Re: Makra v Calcu VYŘEŠENO

Pro Ip : To máš plnou pravdu. Makra o kterých jsem psal nebudou mít vždy úplně takovou podobu, jakou jsem zadal. Používám systémy, které zapisují přímo na konec registru, skok (makra Zápisu) vůbec nepotřebují. Je ale potřeba navázat při přerušení - a nevím jak jinak, nežli typem makra "krok". Také ne všechny generátory potřebují právě tohle. Například mám makro, které vyhodnocuje počet výher z rozpisu (souhrn za všechny tipy) a to má jen zápis určitého počtu druhů kombinací výher. Zapisuji jen počet stejných kombinací určitého druhu. Když ale narazí makro na kombinaci, která by byla vhodná k rozšíření vlastního rozpisu, tak ji zapíšu jinam. Bývá to velká výjimka, pokud tedy naleznu takový tip, řeším to právě takhle. Několik výjimek (pokud vůbec jsou) už výkon systému neovlivní. Věř mi, že hledám optimalizaci všemi způsoby. Chtěl bych ty generátory dát k dispozici, ale osobně mi jde o úplně jiný typ generátoru. Nejsem sázkový maniak jak by se mohlo zdát s toho co píšu. Nejsem ani hacker, který by chtěl lámat hesla smile Ale stejně dík


Moje e-mailová adresa
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte orientaci při vyhledávání řešení JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#18 6. 10. 2011 12:04:26

lp.
Člen
Registrace: 24. 9. 2009
Příspěvků: 842

Re: Makra v Calcu VYŘEŠENO

neutr napsal(a)

Pro IP : Zřejmě máš na mysli pořadí Call Vzorec následně Call Zapis.

Nenám. Ve zveřejněném sešitu je v buňce E3 funkce count. V main_1 je v proměnné E3 odkaz na buňku E3. Volání dispečera ve funkci zápis povolí přepočet funkce count, E3.Value v cyklu vrátí aktuální hodnotu funkce, tj. počet nalezených hodnot.

v main_2 je v E3 hodnota v buňce E3 před zahájením výpočtu bez jakékoliv vazby do listu. Tato hodnota se během cyklu nemění, proto podmínka if během cyklu ani nemůže fungovat. Doporučuji pro main_2 po provedení zápisu doplnit E3 = E3 + 1. Pak to fungovat bude.

Offline

#19 6. 10. 2011 14:09:39

neutr
Člen
Registrace: 8. 3. 2007
Příspěvků: 3,435

Re: Makra v Calcu VYŘEŠENO

Pro Ip : Zkusil jsem to na každý způsob, který mne napadl a nic. Deklaroval jsem duplicitně E3 = E3+1 spolu s původní deklarací. Pak jsem zadeklaroval E3=oSheet.getCellbyPosition(4,2).Value+1. Zmátlo mne také to, že uvádíš funkci count(), když já mám ve vzorci counta() - aby to zastavilo i při textu. Původně tam ta funkce count() byla, a tak jsem si znovu stáhl vlastní soubor jestli je to pravda. Pokud se Ti to povedlo, tak mi to upravené makro Main_2 prosím Tebe pošli. Bylo by to asi to správný ořechový. Je to ten problém, který popisuji jako rozdíl mezi makry "Vzorec1 a Vzorec2". Jsou právě na tom samém rozdílu postavena - ale na rozdíl od Main_1 a Main_2 fungují. Předem dík


Moje e-mailová adresa
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte orientaci při vyhledávání řešení JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#20 6. 10. 2011 14:22:09

neutr
Člen
Registrace: 8. 3. 2007
Příspěvků: 3,435

Re: Makra v Calcu VYŘEŠENO

Pro Ip : Teď mne ještě napadlo, že myslíš název iCount v Cyklu For..Next. To by asi fungovalo i s koncem cyklu "E3". Jenže tenhle "iCount" je jen můj blbej zvyk psát stejné pojmenování pro počítadlo. Funkce For je nepodstatná - stejně tam bude Do..Loop - pokud cyklus nevnořím do makra Main. Potřebuju aby makro zastavilo jen kvůli podmínce If.

Editoval neutr (6. 10. 2011 14:23:02)


Moje e-mailová adresa
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte orientaci při vyhledávání řešení JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#21 6. 10. 2011 20:01:49

sedlacekdan
Moderátor
Místo Nehvizdy
Registrace: 21. 6. 2010
Příspěvků: 617

Re: Makra v Calcu VYŘEŠENO

úprava makra by mohla být takto

Sub Main_2 


oDoc = ThisComponent
    oSheets = oDoc.Sheets
    oSheet = oSheets.getByIndex(0)

B3 = oSheet.getCellbyPosition(1,2)
C3 = oSheet.getCellbyPosition(2,2)
D3 = oSheet.getCellbyPosition(3,2).value


For iCount = 1 To 40


E3 = oSheet.getCellbyPosition(4,2).value


IF D3 = E3 Then 
Print "Překopíruj a smaž výsledky"
Exit Sub
End If


C3.value = B3.value+C3.value
Zapis


Next iCount


End Sub


sub Zapis
dim cislo as long
cislo = 2


C3=thisComponent.sheets(0).getCellRangeByName("C3")
bunka = thisComponent.sheets(0).getCellByPosition(0, cislo)


do while bunka.string <> ""
bunka = thisComponent.sheets(0).getCellByPosition(0, cislo)
cislo = cislo + 1
loop


bunka.value = C3.value


end sub 

Makro Main_2 s úpravou testu If podle lp (to mi nedošlo) a dále je do něj dopsána funkce makra vzorec2.


Makro zapis s úpravou pro rychlejší průběh (stejný výsledek, jiná metoda).


Makro funguje se všemi číselnými hodnotami. Při textové hodnotě ji makro bere jako 0 a nulové jsou tedy i výsledky.


Je to dělané na rychlo, tak jen doufám, že jsem nezměnil činnost makra oproti původnímu záměru.


PS. kampak se ztratilo makro Vykonny?


;o)


Linux Mint 16 Petra - Apache OpenOffice 4.0.1
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte tak orientaci na fóru při vyhledávání řešení problémů
JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#22 6. 10. 2011 20:44:48

sedlacekdan
Moderátor
Místo Nehvizdy
Registrace: 21. 6. 2010
Příspěvků: 617

Re: Makra v Calcu VYŘEŠENO

A nebo takto:

Sub main_zapis_vzorec


oSheet = ThisComponent.sheets(0)
B3 = oSheet.getCellbyPosition(1,2)
C3 = oSheet.getCellbyPosition(2,2)
D3 = oSheet.getCellbyPosition(3,2).value


dim cislo as long
cislo = 2
bunka = thisComponent.sheets(0).getCellByPosition(0, cislo)


For iCount = 1 To 40
  E3 = oSheet.getCellbyPosition(4,2).value


   IF D3 = E3 Then 
    Print "Překopíruj a smaž výsledky"
    Exit Sub
   End If


  C3.value = B3.value+C3.value


 do while bunka.string <> ""
  bunka = thisComponent.sheets(0).getCellByPosition(0, cislo)
  cislo = cislo + 1
 loop


 bunka.value = C3.value


Next iCount


End Sub

Doplnit 1000 řádků (hodnot) trvá cca 6 sekund.


;o)


Linux Mint 16 Petra - Apache OpenOffice 4.0.1
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte tak orientaci na fóru při vyhledávání řešení problémů
JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#23 6. 10. 2011 21:41:12

neutr
Člen
Registrace: 8. 3. 2007
Příspěvků: 3,435

Re: Makra v Calcu VYŘEŠENO

Re sedlacekdan: Dane v tom příkladu ze serveru "ulozto" není Vykonny, protože tam není generátor. Místo toho je tam jen makro "Vzorec". Zítra se podívám na Tvé řešení, ale to, co uváděl Ip nemá žádný vliv. Jedna věc je to, že když dám iterační přírůstek mimo obor čísel N, tak mi do výsledku makro zapisuje text. Jiná věc je ale to, že pomocí Main_2 do výsledků jdou čísla, ale zastaví až na konec cyklu For, a ne na podmínku IF. Možná, že to bude něco takového jak píše Ip. Ale rád bych, aby mi poslal podle něho upravené makra. Mně se to upravit nepovedlo, i když jsem na tom dělal asi 2 hodky.
     Také jsem asi udělal chybu, že jsem hned neposlal příklady chyb. Ta první chyba mne trápí jen málo, protože většinou je výsledkem operace ze které vyhodnocuji podmínku číslo oboru čísel N (celé kladné včetně nuly). Ale pravdou je, že potřebuji také rozseknout problém s přetypováním. Ještě jsem neměl čas podívat se na řešení podle j.pastierika. Zítra zřejmě otevřu nový příspěvek, pošlu zúžený rozsah problému a zřejmě bude nejlepší poslat i konkrétní generátor, na kterém jsem dnes dělal. Je to druh makra, které se zapisuje samo na konec sloupce výsledků. Zřejmě bude lépe demonstrovat problém vyhodnocení podmínky.


Moje e-mailová adresa
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte orientaci při vyhledávání řešení JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

#24 7. 10. 2011 09:06:37

lp.
Člen
Registrace: 24. 9. 2009
Příspěvků: 842

Re: Makra v Calcu VYŘEŠENO

to neutr. 

Pokoušel jsem se vysvětlit, proč podmínka IF v makru main_2 nefunguje. Důvodem je, že v main_1 používáte odkaz a v makru main_2 hodnotu. Řešení naznačil sedlacekdan -  v main_2 musíte hodnotu E3 aktualizovat (načíst) před každým testováním v podmínce if.

Ale. Pokud c makru  vyhodnocujete něco na základě vzorce v listu, je třeba dál sešitu čas na přepočet. Tady ten čas dá funkce zapis (šíleně pomalé opakované volání dispečera). Pokud budete následně optimalizovat rychlost celého makra, podmínka IF opět může přestat fungovat. Bude třeba funkce wait před aktualizací E3 v main_2 nebo před testováním IF v main_1.

Při optimalizaci rychlosti má tedy při tomto přístupu narazíte na limity dost rychle. Proto jsem doporučoval počítat počet nalezených kombinací v makru.

Pro případ přerušení makra a restartu výpočtu je obvyklé periodické ukládání dosažených výsledků a inicializace proměnných při spuštění. Je dobré si uvědomit, že každé ukládání výsledků stojí nějaký čas. Periodu ukládání si můžete odladit jako kompromis mezi rychlostí makra a úspory času při restartu, např. ukládáme výsledky po vygenerování 1000 kombinací, ...

Problém 2. Zajímavé, něco bylo nazančeno výše, opět ale - má smysl iterační přírůstek, pokud to není celé číslo? V tomto případě je asi nejrychlejší volbou na začátku načíst příslušné hodnoty, zkonvertovat je na celá čísla (třeba i long) a dál pokračovat v oboru celých čísel.

Mimochodem, testování shody v jiném oboru než jsou celá čísla pomocí operátoru "=" je chyba (má být: abs(x-y) < eps).

Editoval lp. (7. 10. 2011 09:09:08)

Offline

#25 7. 10. 2011 16:18:48

sedlacekdan
Moderátor
Místo Nehvizdy
Registrace: 21. 6. 2010
Příspěvků: 617

Re: Makra v Calcu VYŘEŠENO

Hodnotu v E3 není ani třeba zjišťovat vzorcem, lze to i makrem stačí minimální úprava:


Sub main_zapis_vzorec


oSheet = ThisComponent.sheets(0)
B3 = oSheet.getCellbyPosition(1,2)
C3 = oSheet.getCellbyPosition(2,2)
D3 = oSheet.getCellbyPosition(3,2).value
E3 = oSheet.getCellbyPosition(4,2)
dim cislo as long
dim srovnej as long
cislo = 2 ' číslo prvního řádku zápisu
bunka = thisComponent.sheets(0).getCellByPosition(0, cislo)
For iCount = 1 To 40000
   IF D3 = cislo - 2 Then 
' cislo zjišťuje pozici řádku, 
'pomocí -2 se dostaneme na přesný počet vypsaných hodnot
    E3.value = cislo - 2 ' a přiřadíme je do buňky
    Print "Překopíruj a smaž výsledky"

    Exit Sub
   End If
  C3.value = B3.value+C3.value
 do while bunka.string <> ""
  bunka = thisComponent.sheets(0).getCellByPosition(0, cislo)
  cislo = cislo + 1
 loop
 bunka.value = C3.value
Next iCount

End Sub 

Možná to ale pak do buňky již nemusíte vypisovat, kontrola proběhla a makro se zastavilo.


;o)


Linux Mint 16 Petra - Apache OpenOffice 4.0.1
Pokud je Váš problém vyřešen, označte prosím svůj příspěvek za "VYŘEŠENÝ"
Zlepšíte tak orientaci na fóru při vyhledávání řešení problémů
JAK OZNAČIT TÉMA ZA VYŘEŠENÉ

Offline

Zápatí