]]>
Tag Archives: Excel
Napi Excel WTF
Summa summarum, a 16 helyiérték hosszú numerikus adat végét az Excel angolosan levágja – sehol egy warning, egy “micsinálsz-hülye-nem-tudok-ekkorát”, semmi. Ha egy szám (szerinte hibásan) szövegként kerül be egy cellába, azért bezzeg tud zöld warning háromszöggel rinyálni. Ennek a bugnak az az igazi szépsége, hogy VBA kódból elő tudsz állítani egy cellában 16 jegyű numerikus tartalmat úgy, hogy a cella azt az adatot jeleníti meg, amit te beleírtál, DE ugyanakkor nem azzal számol, hanem a lecsapott utolsó digitű változattal! Tegnap ez úgy jött elő, hogy egy SUMIF lookup-hoz használta egy rutin a 16 jegyű számot és mivel volt több olyan cella a SUMIF lookup range-ben, amely 16 jegyű numerikus adatot tartalmazott és az első 15 jegyük megegyezett, a rohadék egy kalap alá vette mindet, dacára a 16. digit különbözőségének. A fent leírt SUMIF hiszti megoldása persze egyszerű – numerikus adat helyett szövegként kell használni a cellában a hosszú numerikus értéket (ehhez elég egy ‘ karakter a cellatartalom elejére, vagy a cellaformátum Text állapotúvá kapcsolása). Nem is ezzel van a baj, hanem a módszerrel, ahogy a drágaságos Office alkalmazás a problémát kezeli. ]]>
Hogy dolgozzam így hatékonyan, idióták?!
A probléma Amennyiben Excel 2007 feletti verziókban úgy akarsz conditional formattingot (=feltételes formázás) létrehozni, hogy az képlettel számolódik és a felhasznált képlet relatív hivatkozást tartalmaz, akkor a VBA engine hibásan az conditional formatting target range-ének első celláját használja fel _abszolút_ címzéssel a kért relatív címzés helyett.
A M$ féle “megoldás“
Ne használj relatív címzést. Köszi. Az nem tudom feltűnt-e az ominózus WORKAROUND írójának, hogy a spreadsheet egyik legnagyobb előnye a relatív címzés használata.Mindezek után a probléma közérthetőbben, példával
Képzeld el, hogy az a feladat, hogy 15000 cellát kell ugyanazzal a képlettel számoló feltételes formázással ellátnod (a 15000 cella még “öcsi”, bőven tudnak az userek ettől izmosabbat kérni). Nos, eddig ezt megtehetted úgy, hogy az összes cellára kiadtad a formázási utasítást, mostantól azonban szerintük ez úgy fasza, ha egyesével végigiteráltatod egy ciklussal minden egyes cellát és úgy “oldod meg” azt a problémát, amit az agyatlan codereik generáltak (ugyanis Excel 97-Excel 2007 között ez normálisan működött). Lehet találgatni, melyik mennyi időt vesz igénybe… Charles Simonyi agyoncsapná a codereiteket ezért, ha látná, hogy mit műveltek! Van fogalmatok ott Redmondban arról, hogy ezzel mekkora bajt okoztok a már kész VBA alkalmazásokban, amelyek használatánál a szerencsétlen döntéshozók a conditional formatting által vizualizált inputra támaszkodnak? Forr a vérem. Update: pont ez a feladat jött szembe ma az ügyfélnél, gondoltam mérek egyet: 6610 cellán futott le a kétféle conditional formattinggal ugyanaz az algoritmus – íme a futási eredmény hh:mm:ss bontásban, hogy a redmondi srácok is értsék, mekkora szart kavartak. Conditional formatting, range-re alkalmazva: Conditional formatting, ugyanarra a range-re cellánként iterálva: ]]>VBA Color hiszti
Sub color2RGB(myColor As Long, RGBComponents() As Byte) RGBComponents(0) = (myColor And &HFF0000) \ &H10000 RGBComponents(1) = (myColor And &HFF00&) \ &H100 RGBComponents(2) = (myColor And &HFF&) End Sub
- Azon hexa számok végén lakik &, akik max. 16 biten elférnek, de én 32 bitre szeretném őket erőltetni (=force 32 bit). A 16 bitnél hosszabb számok mögé is pakolhatsz &-t, de azt még az IDE legyilkolja.
- A \ egy spéci osztás, ami az osztás eredményének egész részét adja vissza (=int(a/b))
Function offsetColor(myColor As Long, Optional R As Integer = 0, Optional G As Integer = 0, Optional B As Integer = 0) As Long Dim RGBComponents(2) As Byte Call color2RGB(myColor, RGBComponents()) R = (R + RGBComponents(0)) Mod &HFF If R < 0 Then R = 0 G = (G + RGBComponents(0)) Mod &HFF If G < 0 Then G = 0 B = (B + RGBComponents(0)) Mod &HFF If B < 0 Then B = 0 offsetColor = RGB(R, G, B) End Function
?Hex(offsetColor(myColor:=0, R:=1, G:=2, B:=3)) 30201
MyObject.Color = RGB(255, 0, 0) ' Set the Color property of MyObject to Red.