Znáte to. Máte v Excelu hotovou tabulku, ne-li celý formulář, hrajete si s každým pixelem, aby se vše vešlo na jednu A4, a zjistíte, že potřebujete přidat další informace, sloupec. Ve výsledku to znamená ještě lépe využít prostor, což je často doprovázeno nutností jemnějšího rastru (mřížky) a opětovným slučováním buněk. Práce k zbláznění. Předkládám makro, které ve výběru buněk přidá další sloupce tak, aby došlo ke zjemnění rastru (lidově řečeno se zdvojnásobí počet sloupců ve výběru při zachování původní šířky).
Na úvod tip, jak kontrolovat šířku tabulky před a po změně.
Chování makra ukazují obrázky.
A zde je slíbené makro. Důrazné varování: Změna provedená kódem je nevratná, proto sešit před použitím ukládejte/zálohujte!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | Sub DvakratJemnejsiRastr() Dim rngBunka As Range Dim rngSloupce As Range Dim rngCeleSloupce As Range Dim lngTopStyle As Long Dim lngTopColor As Long Dim lngRightStyle As Long Dim lngRightColor As Long Dim lngBottomStyle As Long Dim lngBottomColor As Long Dim intPocetSloupcu As Integer Dim intSirkaPixely As Integer Dim intNovaSirkaPixely As Integer Dim i As Integer Dim j As Integer Dim dblNovaSirkaColumnWidth As Double 'dots per inch (DPI) Const intPocetBoduNaPalec As Integer = 72 'pixels per inch (PPI) 'Microsoft: 96 PPI, Apple: 72 PPI Const intPocetPixeluNaPalec As Integer = 96 'zamezeni prekreslovani a prepoctu listu Application.ScreenUpdating = False Application.Calculation = xlCalculationManual 'prevzeti zpracovavane oblasti z vyberu bunek Set rngSloupce = Selection.Columns Set rngCeleSloupce = Selection.EntireColumn.Columns 'pocet sloupcu intPocetSloupcu = rngCeleSloupce.Columns.Count 'pro vsechny sloupce For i = 1 To intPocetSloupcu 'skutecne poradi puvodniho sloupce 'po pridavani dalsich sloupcu j = 2 * i - 1 'zjisteni sirky sloupce a prepocet na pixely intSirkaPixely = rngCeleSloupce.Columns(j).Width / intPocetBoduNaPalec _ * intPocetPixeluNaPalec 'nova sirka sloupce bude polovicni... intNovaSirkaPixely = CInt(intSirkaPixely / 2) 'zpetny prepocet na vynucenou velikost v ColumnWidth 'vychazi z regrese na experimentalnich hodnotach dblNovaSirkaColumnWidth = 0.142851762457295 * intNovaSirkaPixely - _ 0.707857121632131 'pridani sloupce vlevo od sloupce nasledujiciho rngCeleSloupce.Columns(j + 1).Insert Shift:=xlToRight 'nastaveni nove sirky puvodniho a pridaneho sloupce rngCeleSloupce.Columns(j).ColumnWidth = dblNovaSirkaColumnWidth rngCeleSloupce.Columns(j + 1).ColumnWidth = dblNovaSirkaColumnWidth 'pro vsechny bunky pridaneho sloupce 'a v nem vyuzite bunky For Each rngBunka In Intersect(ActiveSheet.UsedRange, _ rngCeleSloupce.Columns(j + 1)).Cells 'pokud se nejedna o sloucenou bunku If Not rngBunka.MergeCells Then 'a pritom posledni sloupec... If (j + 1) = (2 * intPocetSloupcu) Then With rngBunka.Offset(0, -1).MergeArea 'nacteni vlastnosti okraju z bunky vlevo lngTopStyle = .Borders(xlEdgeTop).LineStyle lngTopColor = .Borders(xlEdgeTop).Color lngRightStyle = .Borders(xlEdgeRight).LineStyle lngRightColor = .Borders(xlEdgeRight).Color lngBottomStyle = .Borders(xlEdgeBottom).LineStyle lngBottomColor = .Borders(xlEdgeBottom).Color End With End If 'slouceni bunek Range(rngBunka.Offset(0, -1), rngBunka).Merge 'a pro posledni sloupec... If (j + 1) = (2 * intPocetSloupcu) Then With rngBunka.MergeArea 'aplikovani stylu okraju po slouceni .Borders(xlEdgeTop).LineStyle = lngTopStyle .Borders(xlEdgeTop).Color = lngTopColor .Borders(xlEdgeRight).LineStyle = lngRightStyle .Borders(xlEdgeRight).Color = lngRightColor .Borders(xlEdgeBottom).LineStyle = lngRightStyle .Borders(xlEdgeBottom).Color = lngBottomColor End With End If End If Next rngBunka Next i 'povoleni prepoctu listu a prekreslovani Application.Calculation = xlCalculationManual Application.ScreenUpdating = True End Sub |
Pár poznámek. Jak si můžete přečíst v článku Šířka sloupce a výška řádku v Excelu, nastavování šířky sloupce je peklo. V daném případě nestačí načítat a nastavovat vlastnost ColumnWidth, neboť je velmi nepřesná. Proto jsem pro definování nových šířek zpracovával informaci v pixelech (nutné hrátky s DPI) a následně podle sady experimentálních hodnot jsem si zjistil rovnici závislosti mezi ColumnWidth (písmo Calibri 11) a pixely (Zobrazení: Normálně) z lineární regrese.
Mode: normal x,y analysis
Polynomial degree 1, 1786 x,y data pairs.
Correlation coefficient (r^2) = 0.9999998493133465
Standard error = 0.02860707295026823
Coefficient output form: simple list:
-7.0785712163213077e-001
1.4285176245729497e-001
Mode: normal x,y analysis
Polynomial degree 2, 1786 x,y data pairs.
Correlation coefficient (r^2) = 0.9999998516878186
Standard error = 0.028380787766365163
Coefficient output form: simple list:
-6.9971323150786735e-001
1.4282467233145049e-001
1.5092743985123490e-008
Copyright (c) 2013, P. Lutus — http://arachnoid.com. All Rights Reserved.
Závislost je a není lineární. U malých hodnot bohužel hodnoty „ulítávají“ a kdo ví, jak je Microsoft aproximuje. Každopádně pro dostatečnou přesnost není potřeba užít polynom, korelační koeficient to nijak zvlášť neovlivní, jen holt data prokládáme přímkou, která (nelogicky) neprochází počátkem souřadného systému. Proč jsem nepoužil regresi dostupnou přímo Excelu? Trochu lenost použít funkce listu a koeficienty odečtené z rovnice v grafu nejsou dostatečně přesné (korelační koeficient je zaokrouhlen na 1, i když je chybovost podstatná). I přesto, že odchylka korelačního koeficientu od hodnoty 1 je až na 6 desetinném místě, přeci jen u sady sloupců s velmi malou šířkou již není možné zajistit původní celkovou šířku tabulky bez viditelné odchylky. Ale to je prostě daň. A byl tu další problém. Jak víme, Excel umí přidávat sloupce pouze vlevo od výběru. U posledního sloupce tak musíme řešit kupříkladu ohraničení přidaného sloupce, pokud nechceme v algoritmu udělat výjimku. V 95 % případů makro funguje. Občas se mi bohužel stalo, že Excel nenačetl barvu pravého ohraničení a namísto toho použil barvu černou (hodnota 0). Popravdě řečeno neměl jsem již sílu ošetřit těch 5 % případů, ani zjistit příčinu chování (chybu v algoritmu) a zjednat nápravu.
Slučování po řádcích přes všechny sloupce výběru
Jako bonus přikládám kód, který slučuje buňky výběru v každém řádku, a to přes všechny sloupce výběru (podle odhadu je to má druhá nejvyužívanější obecná procedura). Makro uvedené výše již funkčnost obsahuje, ale leckdy vám těch pár řádků zkrátí dobu otravného ručního „znovuslučování“ přes přidaný sloupec.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Sub SloucitPoRadcich() Dim rngRadek As Range Application.ScreenUpdating = False Application.Calculation = xlCalculationManual For Each rngRadek In Selection.Rows rngRadek.MergeCells = True Next rngRadek Application.Calculation = xlCalculationAutomatic Application.ScreenUpdating = True End Sub |
Sešit ke stažení:
uprava_rastru.zip