Az „Excel” fórum célja, hogy keretet adjon az Excel felhasználók széles táborának tapasztalataik megosztására, és lehetőséget a segítséget kérőknek. Az alábbi összefoglaló azért készült, hogy segítse a helyes kérdésfeltevést.
– Írd le szabatosan a problémát. Úgy fogalmazz, hogy ne csak te magad, de a szakértő is megértse, mire szeretnél választ kapni.
– Írd le, hogy milyen verziójú Excellel dolgozol. (Vagy ha nem – ill. nem csak – Excel, akkor micsoda?)
– Írd le, hogy milyen úton indultál el, és hol akadtál el rajta.
– A kérdés megértése szempontjából sokat segíthet, ha feltölteszt egy képet, amin látszik, hogy mit szeretnél, vagy illusztrálja azt.
– Még jobb, ha feltöltesz egy minta munkafüzetet valahová (pl. data.hu). Feltöltés előtt távolítsd el belőle a nem publikus adatokat.
– Ha a feladat jellege olyan, célszerű az "előtte" és "utána" állapotokat bemutatni. (Miből kellene csinálni mit?)
– Ha VBA kódon kell javítani, másold be a releváns kódrészt. Rövid kód mehet hozzászólásba, hosszú kód inkább ide: http://pastebin.com/
– Ha valami nem úgy működik, ahogy kellene, add meg a rendellenes viselkedés jellemzőit, a hibaüzenetet, és a hibát okozó programsort.
Az idő és dátum adatok nagyon ravaszul viselkednek az excelben. Ami a legfontosabb:
Az excel ezeket is számként tárolja és számként számol velük, a következők szerint:
A szám egész része jelenti a dátumot, a törtrésze pedig az időt. Ezért a megformázott idővel különösen nehéz bánni, célszerű a számolások idejére átalakítani számmá:
1 nap=24 óra =1, tehát 12 óra=0,5 , 3 óra 20 perc (=3*60+20)/24
Ezután már minden összeadás "normális számként" múködik. Utána pedig megformázhatod időnek.
Nekem legalábbis így sikerült használható és jó időadatokat kapni.
(De az időformátumból közvetlenül számított értékekben soha nem bízok meg, az sajnos az excel "jóindulatától" függ, mennyire stimmel.) Na jó, biztos van erre valami más szabály is, de arra még nem jöttem rá.
Nem rontottál el semmit. Nem kell csinálnod semmit. Csak engedni, hogy az excel [ó]:pp:mp formátumban közölje az eredményt. Vagy ha nem abban adja, átállítod manuálisan. Az ó:pp:mp formátum ugyanis csak az utolsó (töredék) nap óra-perc-mp-t mutatja. Tehát ennél a formátumnál a nap() függvény is kell a korrekt időhosszhoz.
A legegyszerűbb megoldás a sor magasságának állítása: range("A1").rows.autofit /vagy a menüben kezdőlap-formátum-automatikus sormagasság. Persze ekkor az egész cellatartalmat látod.
Köszi, hogy ennyit dolgoztál vele. Azt hittem, van ennél egyszerűbb megoldás, a beállítások terén vagy valami ilyesmi :) Őszinte leszek: nagyobb az esélye, hogy ezt a makrót nem fogom alkalmazni, mint az, hogy fogom alkalmazni.
Ha a cellából enterrel kilépsz, az utolsó 5 sort látod. Ha visszalépsz a cellára, akkor az elejétől látsz 5 sort. Most a FONTOS! Ha visszaléptél a cellára, F2 és utána enterrel lépj ki, akkor ismét az utolsó 5 sort fogod látni (ha nem így teszel, marad az első 5 sor). Ha alt+entert hagytál üresen a végén, azt levágja a makró.
Private Sub Worksheet_Change(ByVal Target As Range) mutat Target End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range) vmutat Target End Sub
Function mutat(ByRef cl As Range) Dim aml() As String, xx As Integer, yy As Integer If Not IsEmpty(cl) Then Application.EnableEvents = False If Right(cl.Value, 1) = vbLf Then cl.Value = Left(cl.Value, Len(cl.Value) - 1)
aml = Split(cl.Value, vbLf) yy = UBound(aml) If yy > 4 Then cl.Value = "" For xx = yy - 4 To yy cl.Value = cl.Value & aml(xx) & vbLf Next For xx = 0 To yy - 5 cl.Value = cl.Value & aml(xx) & IIf(xx <> yy - 5, vbLf, "") Next cl.Value = cl.Value & "FORD" End If Application.EnableEvents = True End If End Function
Function vmutat(ByRef cl As Range) Dim aml() As String, xx As Integer, yy As Integer If Not IsEmpty(cl) Then If Right(cl.Value, 4) = "FORD" Then Application.EnableEvents = False cl.Value = Left(cl.Value, Len(cl.Value) - 4) aml = Split(cl.Value, vbLf) yy = UBound(aml) If yy > 4 Then cl.Value = "" For xx = 5 To yy cl.Value = cl.Value & aml(xx) & vbLf Next For xx = 0 To 4 cl.Value = cl.Value & aml(xx) & IIf(xx <> 4, vbLf, "") Next End If Application.EnableEvents = True End If End If End Function
Van egy cella, alt+enterrel több sor van benne. Kb 5 sor fér el láthatóan egymás alatt a cellában, mert ekkora a sormagasság. Ha 5-nél több sor van, akkor nem látszik ez a többi.
A cella aljába írok amint írnom kell valamit bele, azaz a legalsó sor az aktuális, ez a legfrissebb. De az igazításnál nem sikerült úgy beállítanom, hogy ez az alsó látszódjon mindig és felfelé "csorduljon". Van ilyenre megoldás?
Azért az valahol nem normális, hogy míg a split-re a Dim ho as Variant-ot képessé lehet tenni addig a Dim ho() as Variant-tal ez nem megy. Én legalábbis hiába próbálkoztam.
Sőt! A ho = Replace("Valami", "m", "k") helyett elég ho="valami". Tehát az értékadás beállítja a $változótípust, amire a split nem képes valamiért. Lehet hogy bug. Viszont képes valami nagyon meglepőre. Ami szintén meghökkentett. A makródban sima változóként definiált ho-t, képes tömbbé alakítani. Amit aztán egy újabb értékadás visszalakít változóvá J))))
Sub bont() Dim ho As Variant ho = "valami" Debug.Print ho ho = Split("jan-feb-marc-apr-maj-jun-jul-aug-szept-okt-nov-dec", "-") Debug.Print ho(11) ''Debug.Print ho ENNÉL KIAKAD ho = "tbando" Debug.Print ho End Sub
Sub bont() Dim ho As Variant ho = Replace("Valami", "m", "k") Debug.Print ho ho = 12 Debug.Print ho ho = Split("jan-feb-marc-apr-maj-jun-jul-aug-szept-okt-nov-dec", "-") Debug.Print UBound(ho) End Sub
Itt már nem kényes arra a split, hogy a ho változó variantnak van definiálva!
Kösz. Az első kérdésemmel kapcsolatban azonban van még egy kis hiányérzetem. Miért nem jó a variant? Én abban a hiszemben voltam/vagyok, hogy a variant bármelyik változótípus helyett használható. Ezek szerint nem minden esetben. Tudsz még eseteket amikor nem?
Sub pamparam() Dim Sh As Object, bat As String, RC As Long Dim FilePath As String, rng As Range, ws1 As Worksheet, ws2 As Worksheet
Set Sh = CreateObject("WScript.Shell") bat = "E:\valami.bat" RC = Sh.Run(bat, 1, True)
Set ws1 = ActiveSheet FilePath = "E:\ez a textfájl készült.txt" Workbooks.OpenText FilePath, xlWindows, , xlFixedWidth Set ws2 = ActiveSheet Set rng = ws2.Range("A1").Resize(ws2.UsedRange.Rows.Count) rng.Offset(, 1).Formula = "=RIGHT(A1,8)" rng.Offset(, 1).Copy ws1.Range("A1").PasteSpecial xlPasteValues
ThisWorkbook.Names.Add Name:="tabla", RefersTo:=ws1.Range("A1").Resize(rng.Rows.Count) ws2.Parent.Close SaveChanges:=False End Sub
Én a favágós Opentext módszert használtam a szövegfájl magnyitására. Alternatively, használhatod a tbando által közreadott QueryTables módszert, nekem azzal csak az a bajom, hogy nem ismer(t)em, és nem áll rá a kezem.
2.Akkor érvényesül a compare, ha a delimiter nem különleges karakter, hanem pl. egy betű. Próbáld ki pl. a példát úgy, hogy a delimiter - helyett felváltva x és X.
A compare állásától függően más-más darabra bontja a szöveget.
Azt nem tudom, hogy az excelből, hogyan lehet bat filet futtatni. De ha már megvan txt file, akkor a vágólapos becopyzása már kiválható a txt file megnyításával. Excel 2007-ben: Adatok/Külső adatok átvétele/Szövegből/file . A 2003-ban is hasonlóan: Adatok/Külső adatok importálás/Adatforrás/file. A többit tudod. Majd a végén töröld az adatokat. Ha folyamat elkezdésekor bekapcsolod a makrórögzítőt kész is a nyers makród, amin nem sokat kell már csiszálni. Ahogy saccolom csak a szövegfile nevének a specifikását kell megoldani és az adattörlést a makró elejére helyezni. A szövegfile specifikálst valahogy így csinálnám: Egy cellába mondjuk a H1-be beírnám a szövegfile nevét(xxxx.txt), majd a beolvasó makróban ennyi változtatást:
With ActiveSheet.QueryTables.Add(Connection:= _ "TEXT;C:UserstbandoDocumentsxxxx.txt", Destination:=Range("$a$1")) _ stb
helyett:
filenev:Range("h1")
With ActiveSheet.QueryTables.Add(Connection:= _ "TEXT;C:UserstbandoDocuments" &filenev, Destination:=Range("$a$1")) _ stb
Most, hogy leírtad a megoldást, bevillant, hogy mintha már kérdeztem volna hasonló problémáról. De nem kizárt, hogy megint ki fog menni a fejemből a megoldás :)
Az első részét jól látod! Ha lefutott, akkor kell a szövegállománnyal foglalkozni. A létrejött szövegállomány állandó helyen van és a sorok végén levő 8 karakterre van szükség. Ennek kellene mondjuk egy tabla nevű tartományban lennie, ami mindig újra generálódik, a hossza futtatásként különböző lehet, ezért az előző tartományt törölni kell és a helyére létre hozni az új elemszámú, ugyanolyan névre elnevezett tartományt. Ezt a tartományt arra használnám, hogy egy excel lapon levő táblázatban az fkeressel ellenőrizzem, hogy szerepel egy bizonyos azonosító a "tabla" nevű listában.
Jelenleg úgy működik, hogy kézzel futtatom a bat állományt, a létrejött szövegállományt megnyitva, az egészet kijelölve vágólapra teszem. Az excel táblában egy lapra másolom a1-től beillesztem a vágólap tartalmát. A szomszédos oszlopban levágom a jobb() fügvénnyel az engem érdeklő részt. A kapott adatokat kijelölöm, elnevezem "tabla" néven és örülök! :)
Pontosítsunk. Az alábbit véltem kihámozni a leírásodból.
1. Megnyitod az Excel munkafüzetet.
2. A munkafüzet megnyitásakor automatikusan lefut egy batch fájl (valami.bat)
3. A batch fájl létrehoz egy szövegfájlt, aminek az elérési útvonala és neve előre tudható, és nem az adott futás során dől el. (Ugye?)
4. A munkafüzetben futó programnak érzékelnie kellene, hogy a batch fájl befejezte a futást, utána pedig a 3. pontban létrehozott szöveges fájlt kellene feldolgoznia.
Itt jönnek a kérdéseim.
Mit jelent az, hogy "névvel ellátott lista"? Hol van ez a lista? Mindig újat kell létrehozni, vagy naplószerűen, folyamatosan írni bele az új dolgokat? Mit értesz tartomány alatt? A szövegfájl minden sora külön cellába kerül, vagy az egész szövegfájl egy cellába? A szöveg sorainak az utolsó 8 karakterét törölni kell, és a többi marad, vagy fordítva, pont az utolsó 8 karakterre van szükség?
Szeretnék szövegállományt feldolgozni az excellel. A szövegállományt egy dosos parancsállomány generálja (mondjuk k.bat). A szövegállomány azonos hosszúságú sorokból áll és a sorok jobboldalából 8 karater hosszan levágva szeretném egy névvel ellátott listában látni a tartalmát.
A megoldandó problémám az, hogy a parancsállományt kellene futtatni a táblázat megnyitásakor és a kapott szövegállományt elhelyezni a névvel ellátott listába. Természetesen a lista mérete változik, minden futtatásnál.
Van egyszerű megoldás arra, hogy egy szövegállomány sorait egy tartományba helyezzük el, vagy meg kell nyitni az állományt és sorról-sorra fel kell dolgozni?