• Как отобразить только последний успешный результат IMPORTXML и игнорировать, если возвращается ошибка?

    ProgrammerForever
    @ProgrammerForever Куратор тега Google Sheets
    Учитель, автоэлектрик, программист, музыкант
    Тут только скрипт поможет. Складировать результаты запросов (дата или номер + данные) в отдельный диапазон скриптом (определить последнюю незаполненную строку, положить данные по таймеру), и оттуда брать последний по дате без ошибок функцией FILTER().
    Ответ написан
    Комментировать
  • Как получить СУММЕСЛИ только видимых ячеек?

    ProgrammerForever
    @ProgrammerForever Куратор тега Google Sheets
    Учитель, автоэлектрик, программист, музыкант
    Не совсем то, но думаю что поможет. Используейте FILTER(Диапазон;Условие1;Условие2;...УсловиеN) для подсчёта суммы.
    например, в вашем случае, в B47 пишем:
    =СУММ(FILTER($C$2:$C$45;$B$2:$B$45=A47))
    Где A47 - фильтр-условие на диаметр трубопровода
    А ещё лучше - сразу сделать так:
    =ЕСЛИОШИБКА(СУММ(FILTER($C$2:$C$45;$B$2:$B$45=A47));0)
    Ответ написан
    Комментировать
  • Как скопировать значение из ячейки, google sheets?

    ProgrammerForever
    @ProgrammerForever Куратор тега Google Sheets
    Учитель, автоэлектрик, программист, музыкант
    Если нужно зафиксировать курс на какой-то дате, используйте функцию GOOGLEFINANCE(код; [атрибут]; [дата_начала]; [дата_окончания|количество_дней]; [интервал])
    Информация о функции на русском
    Например, в A1 пишите так (вместо USD и RUB можно подставить любые другие валюты):
    =GoogleFinance("CURRENCY:USDRUB"; "close"; D2)
    В D2 пишите дату закупки. И курс валюты подтягивается с определенной даты. Т.к. это исторические данные, то они уже не поменяются.
    Ответ написан
  • Существует ли возможность связать GoogleSheets без improtrange?

    ProgrammerForever
    @ProgrammerForever Куратор тега Google Sheets
    Учитель, автоэлектрик, программист, музыкант
    Заверните IMPORTRANGE в FILTER(Данные;Условие1;Условие2...) по условию. Или попробуйте обработать скриптом данные.
    Вот такая штука может пригодиться(чтобы выбрать первые rows строк из данных), как-то сделал и теперь постоянно пользуюсь:
    /**
     * Возвращает rows строк и cols столбцов из array
     *
     * @param {A:A} array Исходный массив
     * @param {10} rows Количество строк. По умолчанию возвращаются все строки
     * @param {1} cols Количество столбцов. По умолчанию возвращаются все столбцы
     * @return Возвращает rows строк и cols столбцов из array
     * @customfunction
     */
    function take(array,rows,cols) {
      if (!array.map) {return array};
      var rows = rows||array.length;
      var cols = cols||array[0].length;
      
      if (array.length>rows) {array.length = rows};
      return array.map(
        function(row){
          return row.map?((row.length>cols)?row.splice(cols,row.length-cols):row):row;
        }
      );
    }
    Ответ написан
  • Как дописать скрипт Google Apps script?

    ProgrammerForever
    @ProgrammerForever Куратор тега Google Apps Script
    Учитель, автоэлектрик, программист, музыкант
    Получать данные по одной ячейке - это ооооооочень долго. Лучше взять все данные сразу в нужном диапазоне, например так:
    var data = ss.getActiveSheet().getRange("A3:A1000").getValues();

    И потом можно обращаться к этим данным по номеру строки и номеру столбца, не забывая что отсчёт идёт с нуля:
    data[row][column]
    Записывать тоже нужно массово. В итоге получится что-то такое:
    function onOpen() { 
      //Выполняется при открытии
      SpreadsheetApp
      .getUi()
      .createMenu('Меню')
      .addItem('Выполнить','doIt')
      .addToUi();
    };
    
    function doIt() {
      try{
        var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); //Текущий лист
        
        var data1 = ss.getRange("A3:E" + ss.getMaxRows()).getValues();
        var data2 = ss
        .getRange("m4:n" + ss.getMaxRows())
        .getValues()
        .filter(function(row) // Убираем пустые строки
                {
                  return row[0]!="";
                }
               );
        
        for (var row2=0;row2<data2.length;row2++){
          for (var row1=0;row1<data1.length;row1++){
            if (data1[row1][0]===data2[row2][0]){
              data1[row1][4]+=data2[row2][1];
              break; //Если значение найдено, дальше не ищем
            };
          };
        };
        
        ss.getRange("A3:E" + ss.getMaxRows()).setValues(data1); //Вывод данных
        SpreadsheetApp.getActive().toast("Готово!");
      }catch(e){ //Если вдруг ошибка
        Logger.log("Ошибка! " + e);
      };
    }

    Демо-таблица
    Ответ написан
    6 комментариев
  • Как сравнить два числа в одной ячейке в Google Таблицы?

    ProgrammerForever
    @ProgrammerForever Куратор тега Google Sheets
    Учитель, автоэлектрик, программист, музыкант
    Используйте REGEXEXTRACT(текст;регулярка) для извлечения кусков текста, чтобы потом сравнить, например что первое меньше второго
    =REGEXEXTRACT(A1;"(\d)+\:") < REGEXEXTRACT(A1;"\:(\d)+")

    Чтобы подсветить соседнюю ячейку, можно использовать Формат - Условное форматирование
    Ответ написан
    1 комментарий
  • Как подсчитать количество импульсов за единицу времени?

    ProgrammerForever
    @ProgrammerForever
    Учитель, автоэлектрик, программист, музыкант
    Как вариант - измерять не частоту, а период следования импульсов. И считать по скользящему среднему за N щелчков. Фон будет считаться медленно, потому что щелчков мало, но если данных будет много - то показания будут изменяться быстрее. Но в любом случае, точность будет предсказуема и примерно одинакова на любой скорости щелчков.
    Ответ написан
    Комментировать
  • Как инициализировать массив Point?

    ProgrammerForever
    @ProgrammerForever Автор вопроса
    Учитель, автоэлектрик, программист, музыкант
    Дело было не в бобине. Проблема была строкой выше, а отладчик подсвечивал именно этот кусок кода. Спасибо откликнувшимся!
    Ответ написан
  • Какой физический смысл импульса?

    ProgrammerForever
    @ProgrammerForever
    Учитель, автоэлектрик, программист, музыкант
    Как только всё уляжется в голове, советую прочитать про Оператор импульса. Когда придёт понимание что все величины и понятия, про которые мусолили годами в школе - всего лишь математика над волновой функцией - будет круто.
    Ответ написан
    Комментировать
  • Как избавиться от Loading?

    ProgrammerForever
    @ProgrammerForever Куратор тега Google Apps Script
    Учитель, автоэлектрик, программист, музыкант
    Если данные сконцентрированы в каком-то месте, можно вместо пользовательской функции использовать просто функцию. Только добавить получение из таблицы аргументов, и вывод результата. Обновление можно повесить на открытие таблицы, на onEdit(event) или на триггер по времени, как нравится. Но такой способ менее информативный, на самом деле. Непонятно обновилось оно или нет. Обычно я в конце таких функций(если нет возможности сделать пользовательскую функцию) добавляю тост о том, что всё завершено.
    SpreadsheetApp.getActive().toast("Функция завершена");
    Ответ написан
    Комментировать
  • Как сделать очистку ячеек выбранного диапазона при активации другой?

    ProgrammerForever
    @ProgrammerForever Куратор тега Google Apps Script
    Учитель, автоэлектрик, программист, музыкант
    Что значит "активная"? Нет события "активная ячейка" но есть событие "ячейка изменилась" - onEdit(event)
    Вот заготовка кода для этой функции:
    function onEdit(event) {
    	//Возникает при изменении ячейки
    	var ss = event.source.getActiveSheet();//Текущий лист
      	var address = event.range.getA1Notation().toUpperCase();//Адрес ячейки
    	var row = event.range.getRow();							//Номер строки
    	var col = event.range.getColumn();						//Номер столбца
    	var newValue = event.value;								//Новое значение
    	var oldValue = event.oldValue;							//Старое значение
    	
      if (["Лист1","Лист2"].indexOf(ss.getName())==-1) return;	//Указываем на каких листах должен работать скрипт
    	
    	//Что-то делаем...
      };

    Вместо "Что-то делаем" впишите нужные действия, например, очистку диапазона. Код для очистки можно сделать макрорекордером Инструменты - Макросы - Записать макрос
    1) Запись
    2) Выделить диапазон
    3) Del
    4) Стоп записи
    Или использовать такой код:
    SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Лист1").getRange("A2:B28").clear();

    Но тут есть момент - эта очистка на том же листе может снова спровоцировать onEdit() и надо с этим бороться, проверяя какой диапазон меняется перед тем как что-то очистить
    if (address !="B2") return;
    Ответ написан
    Комментировать
  • Как подтянуть информацию из нескольких листов в один?

    ProgrammerForever
    @ProgrammerForever Куратор тега Google Sheets
    Учитель, автоэлектрик, программист, музыкант
    Просто нужно указать ссылку на диапазон и обернуть его в ArrayFormula()
    =ArrayFormula(Лист1!A1:Z100)
    Если данные нужно выводить последовательно (например в первом листе 100 строк, во втором 150 и т.п.) а нужно чтобы шло сплошным массивом, то можно использовать декларацию массива, попутно отсеивая пустые строки (в данном случае - по первому столбцу)
    =Arrayformula(
    {
    filter(Лист1!1:200;Лист1!A1:A200<>"");
    filter(Лист2!1:200;Лист2!A1:A200<>"");
    filter(Лист3!1:200;Лист3!A1:A200<>"")
    }
    )

    Демонстрационная таблица
    Ответ написан
  • Гиперссылка Google Apps Script как IMPORTRANGE?

    ProgrammerForever
    @ProgrammerForever Куратор тега Google Sheets
    Учитель, автоэлектрик, программист, музыкант
    Оно и так сохраняется
    Демо-документ
    Ответ написан
    Комментировать
  • Как работает электроскоп и электрометр?

    ProgrammerForever
    @ProgrammerForever
    Учитель, автоэлектрик, программист, музыкант
    В электроскопе есть стержень и лепестки к нему привязанные. В электрометре есть стержень и стрелка, соединённая с ним.
    При электризации заряд распределяется между всеми частями - стержнем и то что к нему прицеплено. Т.к. заряд одинаковый по знаку - лепестки(или стрелка) начинают отталкиваться от стержня. Больше заряд - больше отталкивание.
    Ответ написан
    Комментировать
  • ImportXML многостраничного списка?

    ProgrammerForever
    @ProgrammerForever Куратор тега Google Sheets
    Учитель, автоэлектрик, программист, музыкант
    Там страницы вида "spravkaby.com/phones/mts/page N"
    ={
    IMPORTXML("http://spravkaby.com/phones/mts/page/1";"//div[1]/p");
    IMPORTXML("http://spravkaby.com/phones/mts/page/2";"//div[1]/p");
    IMPORTXML("http://spravkaby.com/phones/mts/page/3";"//div[1]/p")
    }

    и т.п.
    Но всё равно это упрётся в размер обрабатываемых данных. Или в количество запросов в сутки. Проще на чём-нибудь другом парсер сделать
    Ответ написан
    Комментировать
  • Как нарисовать луч функцией исходя из двух точек и на луче вычислить пересечение перпендикуляра от третей точки?

    ProgrammerForever
    @ProgrammerForever
    Учитель, автоэлектрик, программист, музыкант
    1) Вычислить уравнение прямой, походящей через точки 1 и 2
    (x − x₁) / (x₂ − x₁) = (y − y₁) / (y₂ − y₁)
    выражаем у через х, получим уравнение
    y = a₁x + b₁
    2) Построить перпендикуляр из точки к прямой из пункта 1)
    (y – y₃) = -1/a₁ * (x - x₃)
    и выразить у через х, получится
    y = a₂x + b₂
    3) Есть уравнения прямых - надо найти пересечение, т.е. решить систему двух линейных уравнений. Тут методов масса - от простых преобразований до матриц. т.к. у нас уравнения в виде y=f(x), то можно сделать так:
    приравниваем уравнения 1 и 2, избавляемся тем самым от y
    вычисляем x
    подставляем найденное x в любое уравнение
    Ответ написан
    1 комментарий
  • Мониторинг ячейки. Как сделать скрипт мониторинга изменения в ячейке?

    ProgrammerForever
    @ProgrammerForever Куратор тега Google Apps Script
    Учитель, автоэлектрик, программист, музыкант
    Смотрите в сторону onEdit(event) - событие изменения ячеек. Вот заготовка кода:
    function onEdit(event) {
    	//Возникает при изменении ячейки
    	var ss = event.source.getActiveSheet();//Текущий лист
      	var address = event.range.getA1Notation().toUpperCase();//Адрес ячейки
    	var row = event.range.getRow();      //Номер строки
    	var col = event.range.getColumn();  //Номер столбца
    	var newValue = event.value;            //Новое значение
    	var oldValue = event.oldValue;        //Старое значение
    	
      if (["Лист1","Лист2"].indexOf(ss.getName())==-1) return;	//Указываем на каких листах должен работать скрипт
    	
    	//Что-то делаем...
      };

    Интервал времени можно задать в триггерах проекта, навесив триггер по времени на любую функцию.
    Ответ написан
    Комментировать
  • Почему у приложений нельзя посмотреть исходный код?

    ProgrammerForever
    @ProgrammerForever
    Учитель, автоэлектрик, программист, музыкант
    .net декомпилируются до исходников. Решил попробовать декомпилировать программу свою с помощью DotPicker, и офигел, когда даже комментарии свои увидел в коде.
    Ответ написан
  • Как обратиться к текущей ячейке?

    ProgrammerForever
    @ProgrammerForever Куратор тега Google Apps Script
    Учитель, автоэлектрик, программист, музыкант

    функция возвращает сумму значений слева и справа от той ячейки, на которой вызвана

    =ДВССЫЛ("R"&СТРОКА()&"C"&(СТОЛБЕЦ()-1);ЛОЖЬ) + ДВССЫЛ("R"&СТРОКА()&"C"&(СТОЛБЕЦ()+1);ЛОЖЬ)
    Ответ написан
    3 комментария
  • Как написать формулу поиска для текста в ячейке с учетом регистра?

    ProgrammerForever
    @ProgrammerForever Куратор тега Excel
    Учитель, автоэлектрик, программист, музыкант
    Если религия позволяет использовать скрипты, то вот такое будет работать:
    /**
     * Возвращает true, если value содержится в inData как ключ с разделителем delimiter
     *
     * @param {A:A} inData Исходный массив или одиночная строка
     * @param {"key"} value Значение, которое ищется среди слов
     * @param {1} delimiter Разделитель слов. По умолчанию - ","
     * @return Возвращает true, если inData - одиночное значение или аналогичный массив, если inData - диапазон
     * @customfunction
     */
    function isContainText(inData,value,delimiter) {
      var delimiter = delimiter || ",";
      if (inData.map){
        return inData.map(function(el){return isContainText(el,value,delimiter)});
      }else{
        var data = inData.split(delimiter);
        if (!data) return false;
        return data.indexOf(value)!=-1;
      };
    }

    Использование:
    =isContainText(A:A;"Ключ";",")
    Ответ написан
    Комментировать