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

#1 14. 7. 2019 07:12:20

imcon
Člen
Místo Brno
Registrace: 16. 5. 2007
Příspěvků: 191

Jak udělat z tabulky lineární seznam

Potřeboval bych poradit, jak z tabulky vytvořit (konvertovat na) seznam. Má stovky/tisíce řádků a desitky sloupců (cca 10x dvojice sloupců D+E, E+F, ...). Dvojice D+E, E+F,... jsou vždy množství + cena, či něco podobného.
Dokáži to pomocí copy-paste ale to mi trvá cca 10 minut a chci něco rychlejšího a automatického.

Příklad zdroje (nevím jak sem vkládat TAB aby ho editor nesmazal):
A    B    C    D    E    F    ...atd
xyz1    x-qq    Z1    12,4    Z2    5,7    ...atd
yyz2    y-tq    Z1    17,0    Z2    7,7    ...atd
...

Požadovaný výstup:
A    B    C    D   
xyz1    x-qq    Z1    12,4
xyz1    x-qq    Z2    5,7
yyz2    y-tq    Z1    17,0
yyz2    y-tq    Z2    7,7
...


Tedy několik sloupečků (zde A a B) je info stejné vždy k dané položce (A) a potom sloupce C+D (dále E+F, G+H,...) musí být vloženy vždy na nový řádek.

Nic moc mě zatím nenapadlo.
Díky.

Editoval imcon (14. 7. 2019 07:30:15)

Offline

#2 14. 7. 2019 15:48:35

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

Re: Jak udělat z tabulky lineární seznam

Otestujte Imcon V1.
     Můžete si to uložit mezi moje Makra Standard (nad všemi moduly) pouze s deklarací Public takto :

Public Sub Usporadej
Dim iVar, iVal as Integer : Dim sVal as string : Dim a(iVal,3) as Variant
SH = ThisComponent.Sheets(SheetIndex)
oCellCursor = SH.createCursor()
oCellCursor.gotoStartOfUsedArea( False )
SR = oCellCursor.getRangeAddress().StartRow
SC = oCellCursor.getRangeAddress().StartColumn
oCellCursor.gotoEndOfUsedArea( False )
ER = oCellCursor.getRangeAddress().EndRow
EC = oCellCursor.getRangeAddress().EndColumn
oRange = SH.getCellRangeByPosition(SC,SR,EC,ER)
vDescriptor = oRange.createReplaceDescriptor()
iVar = -1
For i = ER To SR Step - 1
For j = 4 To EC Step 2
IF SH.getCellByPosition(j,i).String = "" Then 
GoTo Hopsasa
End If
iVar = iVar + 1
ReDim Preserve a(iVar,3)
a(iVar,0) = SH.getCellByPosition(SC,i).String
a(iVar,1) = SH.getCellByPosition(SC+1,i).String
a(iVar,2) = SH.getCellByPosition(j,i).String
SH.getCellByPosition(j,i).String = ""
a(iVar,3) = SH.getCellByPosition(j+1,i).Value 'Tady pozor očekáváme číslo ale může to být jinak (CSV ap.) 
SH.getCellByPosition(j+1,i).String = ""
Hopsasa:
Next j
ii = 1
For jj = i + 1 To i + iVar
radky = SH.rows
radky.insertByIndex(jj,1) ' vlož na pozici prvního řádku dva nové (pozice řádku, počet nových řádků)
SH.getCellByPosition(SC  ,jj).String = a(ii, 0)
SH.getCellByPosition(SC+1,jj).String = a(ii, 1)
SH.getCellByPosition(SC+2,jj).String = a(ii, 2)
SH.getCellByPosition(SC+3,jj).Value  = a(ii, 3) 'Tady pozor očekáváme číslo ale může to být jinak (CSV ap.)
ii = ii + 1
Next jj
ReDim a(0,3)
iVar = 0
ii = 0
Next i
End Sub

     Není to složité ale ladil jsem to 3 hodiny. Makro je postaveno tak, že by mělo nastartovat kdekoliv nad daty. Tedy start klidně na úseku C5:BA180. V listě nesmí být jiná data nežli zpracovávaná. Při testech jsem testoval i prázdné řádky mezi daty.
     Zlobilo to, takže jsem to ukončil s tím, že data musí startovat na A1 tak jak ukazuje vzor. Jednotlivé řádky mohou být různě dlouhé. Tohle chodí snad dobře.
     Horší je to v případě, že by Vám vadila rychlost zpracování. Lze to postavit celé do array a bylo by to řádově rychlejší. To jsem vzdal kvůli ladění ale mohu dodělat.
     Může tam být problém s čísly. Každý sudý sloupec počínaje sloupcem "D" je deklarován jako číslo. Může se stát že v originále budou hodnoty ve formátu textu (nejčastěji importy z CSV). Tohle se dá snadno řešit :

přepsáním SH.getCellByPosition(j+1,i).Value
na tvar SH.getCellByPosition(j+1,i).String

     Samozřejmě potom je potřeba udělat českou notaci čísel. To je ale jiná kapitola. Když byste potřeboval také toto, nebo něco dalšího - napište.


     Otestujte nejprve s těmi simulovanými daty a pak na datech ostrých.

Editoval neutr (14. 7. 2019 15:51:03)


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 14. 7. 2019 18:38:36

kamlan
Člen
Registrace: 15. 9. 2016
Příspěvků: 87

Re: Jak udělat z tabulky lineární seznam

Zde řešení kopírováním přes getTransferable() což sice není nejrychlejší, ale mělo by to kopírovat i různé formáty buněk.
https://uloz.to/!50zsZq8bUUiU/sloupce-do-radku-1kl-ods
Spustíte to z menu SloupceDoŘádků, vytvoří si to nový list CIL kam budou vložena data.   

Zpracovává buňky do prvního prázdného řádku ve sloupci A, do prvního prázdného sloupce v řádku 1.
Zeptá se vás jestli schovat okno a když dáte OK, tak ho schová, což operaci značně urychlí.
Je tam ukazatel průběhu co se aktualizuje po deseti řádcích, ten počet řádků je v proměnné krokPrubehu.
Jede to po dvojicích podle toho vašeho příkladu: AB jako jakási "univerzální" počáteční hodnota a pak CD/EF/GH/IJ jako další hodnoty, tudíž řádky budou ABCD, ABEF, ABGH, ABIJ atd.
Prázdné hodnoty (nevyplněné buňky) kopíruje též, řádky s prázdnými hodnotami kdyžtak skryjete z menu Data/ Další filtry/ Standartní filtr...
Ukázkové hodnoty jsou z toho neutrova příkladu, zatímco jsem to testoval pouze na těch vašich pár ukázkových hodnotách, tak neutr už zveřejnil svůj výsledek a tak jsem po shlédnutí jednoduše zkopíroval jeho rozšířené testovací hodnoty :-).

Offline

#4 14. 7. 2019 22:21:51

imcon
Člen
Místo Brno
Registrace: 16. 5. 2007
Příspěvků: 191

Re: Jak udělat z tabulky lineární seznam

Teda pánové - kloubouk dolů!

Opět se potvrdilo, že toto fórum má super přispěvovatele a ve většině případů pomůže.
Mockrát děkuji, dnes již nevyzkouším, protože dokončuji už další práci ale pokud jeden či druhý způsob rozchodím, bude se nám hodit.
Škoda, že zde není možné poslat nějaké credity :-) ...

Offline

Zápatí