stoffn
Goto Top

IF-Funktion, die nichts tut bei false

Hallo! Ich habe eine recht lange IF-Funktion, die auch soweit funktioniert. Ich arbeite mit google sheets.
Sie soll mir etwas ausgeben (z.B. in A3), wenn ich einen gewissen Text in z.B. A8 eingebe. Anderenfalls soll sie aber am Wert der Zelle nichts ändern, wenn ich etwas anderes eingebe. Es geht aber nur um 2 Zustände, 1 und 0. Wenn ich Text1 eingebe erscheint also eine 1, bei Text2 eine 0 und wenn ich z.B. Text 3 oder 4 eingebe, soll der Wert, der schon in A3 steht, nicht verändert werden.
Versuche ich das als Formel (also zb. IF (A8=text3;A8+0;A8+0) , wird immer ein Zirkelbezug festgestellt, logischerweise.
Gibt es eine Möglichkeit, dass nichts ausgegeben wird, wenn ich was eingebe?
Wie gesagt, für Text 1 und 2 funktionierts, aber Text3 funktioniert dann nicht mehr. Text3 setzt das ganze dann halt immer auf 0 oder 1, je nach dem, wie die Funktion lautet. Und das soll nicht sein.

Kann mir dabei jmd. helfen?

Content-ID: 315206

Url: https://administrator.de/contentid/315206

Ausgedruckt am: 19.11.2024 um 14:11 Uhr

colinardo
colinardo 14.09.2016 aktualisiert um 10:32:07 Uhr
Goto Top
Hallo Stoffn,
du kannst eine Zelle nicht mit einer Formel und einem vom Benutzer eingetragenen Wert belegen, beides geht nicht. Ebenso kannst du mit einer Formel keinen Wert einer anderen Zelle ändern. Hier bleibt dir also bei Google-Sheets ein JavaScript das das für dich erledigt:

Dazu öffnest du unter Tools > Scripteditor den selbigen und erstellst einen Trigger (Ressourcen > Aktuelle Trigger des Projekts und erstellst dort folgenden Trigger:

screenshot

Dann fügst du den unten stehenden Code in das Codefenster ein:
function myFunction(e){
  var sheet = SpreadsheetApp.getActiveSheet();
  var rngOut = sheet.getRange("A3");  
  if (e.range.getRow() == 8 && e.range.getColumn() == 1){
    switch(e.range.getValue()){
      case 'text1':  
        rngOut.setValue(1);
        break;
      case 'text2':  
        rngOut.setValue(0);
        break;
    }
  }
}
Wenn du jetzt den Inhalt von A8 z.B. auf "text1" oder "text2" änderst wird A3 verändert, ansonsten behält A3 seinen aktuellen Wert.

https://docs.google.com/spreadsheets/d/1JgvhFx97Oa3jpqEYsUcnAazC2x85iG1p ...

Grüße Uwe
Stoffn
Stoffn 14.09.2016 um 10:36:02 Uhr
Goto Top
Das ist so schon so weit richtig, danke. Ich brauche das allerdings fortlaufend nach unten. Also für die komplette Spalte A. Sprich, A3 bleibt gleich, es soll aber ab A8 gezählt werden, wenn Werte eingetragen werden.
A8= Text1, dann A3=1
A9= Text2, dann A3=0
A10=Text(3,4,5,6 etc), dann A3=keine Änderung zu A9
A11=Text1, dann wieder A3=1 usw. bis nach unten.

Deine Funktion ist also so schon super, es sollte aber immer die letzte Zeile der Spalte prüfen und sich nach diesem Wert richten. Bin Neuling, was das googlescript bzw. das scripten generell angeht.

Habe dafür eine normale Funktion, aber wie schon erwähnt, das geht nicht mit mehreren Werten, ohne, dass der eine den anderen Wert immer wieder 0 oder 1 setzt, auch wenn er das nicht tun soll (IF macht das mir nicht anders).
colinardo
colinardo 14.09.2016 aktualisiert um 11:18:45 Uhr
Goto Top
Deine Funktion ist also so schon super, es sollte aber immer die letzte Zeile der Spalte prüfen
Siehe das Demo-Sheet das ich oben verlinkt habe.

p.s. Das nächste mal verrate uns das doch direkt, so dass wir hier nicht doppelt Arbeit haben. Danke!
Stoffn
Stoffn 14.09.2016 um 15:16:52 Uhr
Goto Top
Ich kann das Demosheet leider nur lesen. Soll ich Berechtigung anfordern? Oder kann ich die Funktion auch irgendwo sehen, wenn ich nur Lesezugriff habe?
Stoffn
Stoffn 14.09.2016 um 15:18:18 Uhr
Goto Top
Habe eine Kopie erstellt, das geht natürlich auch. Ich gucke mir das mal an. Vielen Dank!
colinardo
colinardo 14.09.2016 aktualisiert um 15:22:57 Uhr
Goto Top
Das Script findest du im Skript-Editor, du musst aber bei einer Kopie den Trigger wie oben beschrieben neu erstellen, da dieser nicht mit übertragen wird!
Stoffn
Stoffn 14.09.2016 aktualisiert um 15:26:51 Uhr
Goto Top
Ja ich hatte nur den Trigger für die eine Funktion gesetzt, nun ist alles klar! Danke!

Und wenn ich das gleich z.B. für Spalte B und C noch möchte? Also auch mit den Ergebnissen jeweils nur in diesen Spalten.
colinardo
colinardo 15.09.2016 aktualisiert um 09:19:12 Uhr
Goto Top
Zitat von @Stoffn:
Und wenn ich das gleich z.B. für Spalte B und C noch möchte? Also auch mit den Ergebnissen jeweils nur in diesen Spalten.
Sorry hatte deine Ergänzung leider nicht mehr mitbekommen. Sheet von oben ist aktualisiert.

Hier noch der Code für Spalte A-C. Die Ausgabezeile der jeweiligen Spalte legst du mit der Variablen intRowOut fest. Willst du das ganze auf noch mehr Spalten erweitern passe einfach die IF-Bedingung
if (currentCol >= 1 && currentCol <= 3)
an deine Bedürfnisse an.
Achtung, die erste Funktion wurde auch aktualisiert.
function lastValue(column) {
  var lastRow = SpreadsheetApp.getActiveSheet().getMaxRows();
  var values = SpreadsheetApp.getActiveSheet().getRange(1,column,lastRow,1).getValues();
  for (; values[lastRow - 1] == "" && lastRow > 0; lastRow--) {}  
  return values[lastRow - 1];
}

function myFunction(e){
  // aktuelles Sheet festlegen
  var sheet = SpreadsheetApp.getActiveSheet();
  // Zeile der jeweiligen Spalte die verändert wird
  var intRowOut = 3;
  var currentCol = e.range.getColumn();
  // nur bei Änderungen in Spalten A-C reagieren
  if (currentCol >= 1 && currentCol <= 3){
    switch(lastValue(currentCol)){
      case 'text1':  
        sheet.getRange(intRowOut,currentCol).setValue(1);
        break;
      case 'text2':  
        sheet.getRange(intRowOut,currentCol).setValue(0);
        break;
    }
  }
}
Grüße Uwe
Stoffn
Stoffn 15.09.2016 um 09:51:10 Uhr
Goto Top
Super! Ich schaue es mir mal an! Danke auch, für die zusätzliche Erklärung noch und die Mühe!
Stoffn
Stoffn 30.11.2016 um 16:38:19 Uhr
Goto Top
Ich habe die Funktion angepasst nun schon länger in Benutzung. Und sie arbeitet sehr gut. Doch kommt es vor, dass sich Fehler einschleichen, wenn z.B. Werte in den Spalten zu schnell eingetragen werden (copy&paste). D.h. die Funktion wird mal ausgeführt, mal nicht. Vermutlich, weil das google dann zu schnell geht und so manche Eintragungen übersehen werden.
Wie ändere ich denn eine solche Funktion auf eine zeitliche Steuerung? Sprich, dass sie jede Minute die Werte der Spalten überprüft, und nicht immer onEdit(e)? Den Trigger einfach auf minütlich setzen bringt natürlich nichts.
Ziel ist, dass die Funktion absolut fehlerresistent ist, Fehler also ausgeschlossen sind. Auch wenns ineffizient ist, würde eine zeitliche Steuerung (also eine minütliche Aktualisierung der Werte), solche Fehler ausschließen.
Reicht es, für die Funktion selbst im Script einen Zeittrigger zu erstellen?

Also in Form von:

function createTimeDrivenTriggers() {
// Trigger every 6 hours.
ScriptApp.newTrigger('myFunction')
.timeBased()
.everyHours(6)
.create();
colinardo
colinardo 30.11.2016 aktualisiert um 20:33:59 Uhr
Goto Top
Reicht es, für die Funktion selbst im Script einen Zeittrigger zu erstellen?
Du kannst im Script-Editor einen Zeittrigger deiner Wahl anlegen (Ressourcen > Trigger des aktuellen Projekts)
Du musst dann in der Funktion nur die variablen Bezüge wie SpreadsheetApp.getActiveSheet() durch feste ersetzen, also den Sheetnamen fest angeben (z.B. SpreadsheetApp.getSheetByName("Blattname")), da es ja zu einem variablen Zeitzeitpunkt kein aktives Sheet geben kann. Ebenso die Event-Variable e hat dort anderen Inhalt und enthält keinen Zellbezug mehr, die musst du natürlich auch durch feste Zellen tauschen bzw. in deinem Fall dein Bereich mit einer For-Schleife durchlaufen und alle Zellen prüfen.

Wenn es auf Konsistenz ankommt würde ich aber bestimmt nicht auf Google-Sheets zurückgreifen!! Du solltest dringend über eine Datenbank-Anwendung auf Browserbasis nachdenken. Google-Sheets ist für sowas einfach sehr schlecht geeignet. Aber ich schätze hier fehlt einfach mal wieder das Wissen.
Stoffn
Stoffn 01.12.2016 um 09:19:19 Uhr
Goto Top
Wie man den Zeittrigger manuell setzt, weiss ich ja. Ging schon eher um die fehlerresistenz, bzw. wie man die Funktion dahingehend besser machen könnte. Aber gut, dann überdenke ich das nochmal und suche ggf eine andere Lösung. Danke!