Autor
|
Thema: VBA Excel Range Befehl funktioniert auf sheet 1, aber auf sheet 2 nicht?!? (1398 mal gelesen)
|
sto.teac Mitglied CAD Designer / LV series production
Beiträge: 66 Registriert: 23.07.2010
|
erstellt am: 01. Dez. 2015 17:43 <-- editieren / zitieren --> Unities abgeben:
Hallo Leute, ich bin mal wieder auf eure tatkraeftige Unterstuetzung angewiesen! Ich habe mir eine kleine Routine gebaut, die mir die erste leere Zeile auswirft. Soweit so gut. Mein problem ist, dass die Routine nur auf einem Tabellenblatt funktioniert und ich nicht herausfinde woran das liegt. Daher stelle ich euch mal den betroffenen Code zur Verfuegung und hoffe, dass ihr den Grund erkennt. Vielen dank im Voraus. Declarationen:
Code: Public ROWempty As Integer 'erste leere Zeile Public WSactive As Worksheet 'aktives WS Public WSnael As Worksheet 'WS mit Daten Public WSmail As Worksheet 'WS zur Erstellung Text fuer Email Public SelVal As Integer 'Case Variable fuer gedrueckten button
Aufruf des Makro: Code: Sub createEmail()SelVal = 3 Call Main End Sub Sub Main() Set WSnael = ActiveWorkbook.Worksheets("NAELdriven") Set WSmail = ActiveWorkbook.Worksheets("MAILoutput") Select Case SelVal Case 1 Call unHide_all Call zellen.EmptyROW(WSnael, "c5") Call zellen.SelectROWall Call zellen.SelSort_due Case 2 Call zellen.EmptyROW(WSnael, "c5") Call zellen.SelectROWall Call zellen.SelSort_KOabschl Call Hide_done Case 3 Call zellen.grabData End Select End Sub
Code: Sub grabData()Dim DataRow As Integer DataRow = Selection.Cells(1).Row Call createTable(DataRow, "NAEL") Call createTable(DataRow, "KO_Abschl") End Sub Private Sub createTable(useRow As Integer, useCol As String) Dim NAELtxt, NAELname, NAELtask, KOABtxt, CADname, DERIVATEtxt, GAMStxt, PQMtxt As String Const NAELhead As String = "NAEL" Const KOABhead As String = "KO-Abschl." Const DERIVATEhead As String = "Derivate" Const GAMShead As String = "gAMS" Const PQMhead As String = "PQM" useCol = Range(useCol).Column Call EmptyROW(WSmail, "a1") Debug.Print useCol End Sub
die Routine: Code: Sub EmptyROW(WSactive As Worksheet, activeRange As String) WSactive.Activate Debug.Print activeRange WSactive.Range(activeRange).End(xlDown).Offset(1, 0).Select '.Offset(1, 0).Paste 'erste leere zelle nach range anwaehlen ROWempty = Selection.Cells(1).RowFor i = 1 To 12 If IsEmpty(Cells(ROWempty, i)) = False Then MsgBox ("Leere Zeile konnte nicht ermittelt werden! Macro wird beendet" & Chr(13) & "Siehe Zeile: " & ROWempty) End End If Next End Sub
Aufruf der Routine die funktioniert: Code: Call zellen.EmptyROW(WSnael, "c5")
Aufruf der Routine die nicht funktioniert: Code: Call zellen.EmptyROW(WSmail, "a1")
Fehlermeldung: Zitat: Run-time error 1004: Application-defined or object-defined error
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
sto.teac Mitglied CAD Designer / LV series production
Beiträge: 66 Registriert: 23.07.2010
|
erstellt am: 01. Dez. 2015 18:43 <-- editieren / zitieren --> Unities abgeben:
update: ich habe ein Muster gefunden. Wenn die Angewaehlte Zelle, die den Startpunkt markiert, (plus die darunter) leer sind entsteht der Fehler. Sind diese beiden Zellen befuellt funktioniert es. Kann mir das bitte jmd erklaeren? Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KlaK Ehrenmitglied V.I.P. h.c. Dipl. Ing. Vermessung, CAD- und Netz-Admin
Beiträge: 2624 Registriert: 02.05.2006 AutoCAD LandDesktop R2 bis 2004 Civil 3D 2005 - 2014 Plateia, Canalis Visual Basic
|
erstellt am: 01. Dez. 2015 22:52 <-- editieren / zitieren --> Unities abgeben: Nur für sto.teac
Hallo sto.teac Deine Codeschnipsel sind leider etwas verwirrend, sinnvoller wäre es gewesen eine Arbeitsmappe mit dem Code hier einzustellen. Ich vermute mal Du hast ein Modul "Zellen" in dem sich die Subroutinen befinden? Und dann gibt es noch ein Formular in dem sich die Main-Prozedur befindet? Ferner wäre es noch schön gewesen zu erfahren wo die Fehlermeldung auftaucht (Markierung im Code) Also gut, Fehlermeldung taucht hier auf: WSactive.Range(activeRange).End(xlDown) (den Rest .Offset(1, 0).Select habe ich mal weggelassen) Dazu solltest Du mal überlegen was diese Funktion macht. Im Prinzip sucht sie in die angegebene Richtung die letzte belegte Zelle. Wenn jetzt zum Beispiel in A5 ein Wert stehen würde wäre dass das Ziel. Ist die Spalte A leer oder nur in A1 ein Wert, was soll die Funktion dann finden? Natürlich kann man jetzt darüber streiten warum die Funktion mit einem Fehler abbricht und nicht einfach auf der aktuellen Zelle stehen bleibt. Ist halt so ... Wenn ich Deinen Kommentar lese (erste leere zelle nach range anwaehlen) würde ich mal sagen da hast Du Dir eine falsche bzw. in meinen Augen zu fehleranfällige Funktion ausgesucht. Traue keinem User, evtl. macht er "weiter unten" eine Randnotiz. Dann bekommst Du ein Problem ... Grüße Klaus
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
sto.teac Mitglied CAD Designer / LV series production
Beiträge: 66 Registriert: 23.07.2010
|
erstellt am: 02. Dez. 2015 02:49 <-- editieren / zitieren --> Unities abgeben:
vielen dank fuer die erlaeuterung ... soweit hast du alles richtig herausgelesen mit dem user habe ich eigentlich recht wenig probleme, ausser dass er anscheinend nicht coden kann (die tabellen nutze normaler weise nur ich persoenlich) hast du einen tipp fuer mich, wie ich die gewuenschte funktion/ bzw das gewuenschte ergebnis eleganter und weniger fheler anfaellig erreiche? vielen dank im voraus und beste gruesse aus SC Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KlaK Ehrenmitglied V.I.P. h.c. Dipl. Ing. Vermessung, CAD- und Netz-Admin
Beiträge: 2624 Registriert: 02.05.2006 AutoCAD LandDesktop R2 bis 2004 Civil 3D 2005 - 2014 Plateia, Canalis Visual Basic
|
erstellt am: 02. Dez. 2015 14:18 <-- editieren / zitieren --> Unities abgeben: Nur für sto.teac
Ich weiß am Anfang ist es immer etwas schwierig und für manche Funktionen verwendet man zunächst den Makroaufzeichner. Leider schleichen sich dadurch immer so Sachen ein, dass man unnötigerweise mit Range-Objekten und Selections arbeitet. Dabei sind viele Sachen mit einer einfachen Zellenbetrachtung einfacher durchzuführen. Auch verwende ich für Programme (auch wenn es übersichtlicher ist) ungern die "C5"-Schreibweise sondern spreche die Zellen eher über den Wert an, wodurch sich die folgenden Änderungen ergäben: Code: ' Erzeugt Fehler bei End ' WSactive.Range(activeRange).End(xlDown).Offset(1, 0).Select '.Offset(1, 0).Paste 'erste leere zelle nach range anwaehlen ' ROWempty = Selection.Cells(1).Row ' ' Alternative: Dim bLeer As Boolean: bLeer = False Dim tRow As Long Dim tCol As Long tCol = Range(activeRange).Column tRow = Range(activeRange).Row While Not bLeer ' Achtung bei Cells wird Spalte, Zeile getauscht ! ' aus Range("C5") wird cells(5,3), If IsEmpty(WSactive.Cells(tRow, tCol)) Then ' Alternative mit Überprüfen auf leeren Textinhalt: ' If IsEmpty(WSactive.Cells(tRow, tCol)) _ ' Or Trim(WSactive.Cells(tRow, tCol)) = "" Then bLeer = True Else tRow = tRow + 1 End If Wend ROWempty = tRow
Dann ist mir noch folgendes aufgefallen:
Code: Private Sub createTable(useRow As Integer, useCol As String)Dim NAELtxt, NAELname, NAELtask, KOABtxt, CADname, DERIVATEtxt, GAMStxt, PQMtxt As String
Du solltest Dir darüber im klaren sein, dass nur PQMtxt als String definiert wird. Alle anderen Variablen sind vom Typ Variant Grüße Klaus Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
sto.teac Mitglied CAD Designer / LV series production
Beiträge: 66 Registriert: 23.07.2010
|
erstellt am: 03. Dez. 2015 20:12 <-- editieren / zitieren --> Unities abgeben:
vielen Dank fuer deine Bemuehungen ... aber erschreckend ist, dass ich die Loesung ja ein paar Zeilen drunter selbst schon genutzt habe Manchmal sieht man den Baum vor lauter Wald nicht (ich weiss gehoert anders herum, aber so klingt es noch besser ^^) bzgl. der Dim ... gibt es einen Weg der Kurzform (Klammer setzen oder so), oder muss ich wirklich jedes mal "as String" dahinter packen? Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KlaK Ehrenmitglied V.I.P. h.c. Dipl. Ing. Vermessung, CAD- und Netz-Admin
Beiträge: 2624 Registriert: 02.05.2006 AutoCAD LandDesktop R2 bis 2004 Civil 3D 2005 - 2014 Plateia, Canalis Visual Basic
|
erstellt am: 03. Dez. 2015 21:33 <-- editieren / zitieren --> Unities abgeben: Nur für sto.teac
Auf Modulebene kannst Du das über die DefType-Anweisung machen Also z.B.: DefStr s-t ' Strings, Texte dann werden alle Variablen die mit s.., S.., t.. oder T.. anfangen als String behandelt (innerhalb des Moduls). Und auch alle Funktionen, z.B. gäbe folgende Anweisung automatisch einen Stringwert zurück: Function TextTeilen ( sLesen ) ' beide Variablen sind vom Typ String Sinnvoll wäre dann natürlich auch die anderen Typen zu setzen: DefInt i ' Integer DefLng L ' Long DefBol b ' Boolean Einzelne Dim sind dann nicht mehr erforderlich, der Anfangsbuchstabe einer neuen Variablen legt den Datentyp fest. Natürlich kann man über "Dim Teile as Integer" immernoch einzelne Variablen anders definieren, fördert aber nicht die gewünschte Interpretierbarkeit. Andere Möglichkeit (aus alten Tagen) wäre noch mit Typkennzeichen zu arbeiten. Hier wird der Typ über das letzte Zeichen definiert, also z.B. sText$ für Strings, tLong& für Long, tInt% für Integer tDbl# für Double-Werte Hier bräuchte man auch keine Dim Anweisung, aber diese Schreibweise wird eigentlich nicht mehr verwendet Aber man kann es sich doch einfach machen, "as String," beim ersten Mal markieren, strg+c und dann nur noch strg+v Oder noch übersichtlicher, jeden Wert in eine neue Zeile und mit Kommentar dazuschreiben für was er verwendet wird. Wenn Du nach 10 Jahren das Programm mal wieder hervorziehst wirst Du froh darum sein. Ich weiß nicht wieviele Programme ich da in der Zwischenzeit nach Analyse ergänzt habe. Bei neueren Programmen steht zum Teil mehr Beschreibung als Code drin ...
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KMassler Ehrenmitglied V.I.P. h.c. CAD Admin + Mädchen für Alles...
Beiträge: 2657 Registriert: 06.11.2000
|
erstellt am: 04. Dez. 2015 08:30 <-- editieren / zitieren --> Unities abgeben: Nur für sto.teac
|
runkelruebe Ehrenmitglied V.I.P. h.c. Straßen- / Tiefbau
Beiträge: 8075 Registriert: 09.03.2006 sw: WinXPPro SP2 Office2007 SP1 Civil3D 2010 SP2 ET; DACH; Extensions STRATIS bis 12.1 ARRIBAbauen 12.4 ARRIBAfinanzen ------------------- hw: NVIDIA GeForce FX 5200 onboard: Intel 82865G 2x 20" 3GHz, 2GB RAM
|
erstellt am: 04. Dez. 2015 09:20 <-- editieren / zitieren --> Unities abgeben: Nur für sto.teac
|
KlaK Ehrenmitglied V.I.P. h.c. Dipl. Ing. Vermessung, CAD- und Netz-Admin
Beiträge: 2624 Registriert: 02.05.2006 AutoCAD LandDesktop R2 bis 2004 Civil 3D 2005 - 2014 Plateia, Canalis Visual Basic
|
erstellt am: 04. Dez. 2015 11:24 <-- editieren / zitieren --> Unities abgeben: Nur für sto.teac
Hi Ruebe, Das mit dem Excel-Brett hatte ich mir auch schon gedacht Zum Link: Das Abkürzen mit Typkennzeichen ist für routinierte Programmierer eine schöne Sache, m.E. sollte man hierauf aber verzichten (ebenso wie auf die DefType - Anweisungen), da es für eher selten programmierende Mitarbeiter eher verwirrend ist (Stichwort: Warum ist strText das gleiche wie strText$ aus der Dim? Was bedeutet jetzt % ? & ? ) Wenn man überlegt wie viel Zeit man oft für Überlegungen zum Programmablauf investiert, sollten die paar Sekunden für einen einfach lesbaren Code auch drin sein. Und der später das Programm betreuende wird es Euch danken. (Merkt man dass ich mich langsamen dem Ruhestand nähere ? ) Grüße Klaus Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|