Pull to refresh

Студентам-технарям: автоматизируем оформление курсачей в таблицах Google

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

Т. е. так нельзя: S = π⋅R² = 314 [м²]
надо так: S = π⋅R² = 3,14⋅10² = 31,4 [м²]

Причина в том, что расчеты сдавались на бумаге, а профессорам проверять все это не видя цифр неудобно. Обычно расчеты мы делали в Excel, оформлять формулы и подстановку цифр приходилось вручную, и если исходные данные менялись, все автоматом пересчитывалось и оформление снова переделывали вручную. Я то понимал, что с такой примитивной задачей, как подставлять циферки в формулы, компьютер может справиться самостоятельно, но, как оказалось, такой возможности не реализовано ни в Mathcad, ни в Mathematica, ни в Excel.

В попытках найти подходящую программу я перепробовал много всего, но нашел только самописную BreadsCAD Владимира Воронова, такого же студента, что доказало, что я не один такой странный. Самописный продукт плохо интегрировался с другими программами, работал не без багов и, конечно, не был кроссплатформенным. А тогда, как раз стали появляться планшеты, реклама первого айпада взрывала интернет, демонстрируя запредельный уровень комфорта, и моей заветной мечтой стало делать курсовые, расположившись по-барски полулежа в кровати. Я даже начал изучать очень кроссплатформенный ActionScript 3.0, чтобы написать собственную программу, но, как оказалось, сделать это с нуля не так просто, хоть я и достиг в AS3.0 определенных успехов. В общем, до конца универа я оформлял курсачи вручную с легким чувством недовольства этим несовершенным миром.

Закончив универ, по работе иногда приходилось что-нибудь заскриптовать на VBA Excel и как-то меня осенило, что решение было совсем рядом. И вот, несколько лет назад, без всякой практической необходимости, а ради реализации юношеской мечты я сделал эту штуку MS Excel и Word (скрипт не только оформлял формулы в Excel, но и мог экспортировать расчет в Word с такими изысками, как дроби, квадратные корни, верхние и нижние индексы и т.п.). Нашел винтажное видео того, как это работало:


Простите за качество, записывал с экрана на телефон. Кстати эту штуку у меня даже купили сосед в студенческой общаге за 500 р. (Привет, Егор!)

А недавно пришло в голову более лаконичное решение в виде функции OpenCalc для Google Spreadsheets, получив действительной кроссплатформенный инструмент. Ну и не удержался, чтобы что-нибудь не посчитать этой штукой (учился я на теплоэнергетика, поэтому тема расчетов такая специфичная): https://docs.google.com/spreadsheets/d/14l52J9im79leO0ttKhyrHU4b03i-2bHONszPlgA0tFk

Если кому то понадобится, то вот код:

//Функция представляения формулы в нужном виде. Аргументы:
//symbol - ячейка с обозначением параметра
//value - ячейка с формулой и результатом
//unit - ячейка с размерностью
//symbolFormula - опционально - собственное изображение формулы, если обозначение стандартное обозначение не устраивает. Например если в С85: =СУММ(G81:R81), можем использовать свою формулу: =OpenCalc(B85;C85;D85;"=∑nз⁽³⁰⁾")
//pattern - опционально - шаблон, определсяет в каком виде будет выводиться формула. По умолчанию 'Symbol_SymbolFormula_ValueFormula_Value_Unit_', при необходимости можно убрать подстановку значений или размерность

function OpenCalc(symbol,value,unit,symbolFormula,pattern){
  pattern = pattern || 'Symbol_SymbolFormula_ValueFormula_Value_Unit_'; 
  if (unit != "") unit = ' [' + unit + ']';
  
  var arguments = SpreadsheetApp.getActiveRange().getFormula().split(' ').join('').slice(10,-1).split(';'); //аргументы функции OpenCalc (адреса ячеек), например = B11,C11,D11
  var formula = SpreadsheetApp.getActiveSpreadsheet().getRangeByName(arguments[1]).getFormula(); //вытаскиваем формулу из ячейки C11
  value = SpreadsheetApp.getActiveSpreadsheet().getRangeByName(arguments[1]).getDisplayValue(); //вытаскиваем значение из ячейки C11
  var symbolCol = SpreadsheetApp.getActiveSpreadsheet().getRangeByName(arguments[0]).getColumn(); //столбец с обозначениями параметров (B)
  var valueCol = SpreadsheetApp.getActiveSpreadsheet().getRangeByName(arguments[1]).getColumn(); //столбец с формулами и результатом вычисленй (С)
  var unitCol = SpreadsheetApp.getActiveSpreadsheet().getRangeByName(arguments[2]).getColumn(); //столбец с размерностью (D)
  
  
  var valueFormula='';
  if (symbolFormula === undefined) {
    symbolFormula = replaceFormula(formula,symbolCol);
    valueFormula = replaceFormula(formula,valueCol);};
  if (symbolFormula == valueFormula) valueFormula = ''; //если в формуле введены значения, а не ссылки на ячейки, например c = 3*10^8, подстановка значений не требуется
  var unitFormula = replaceFormula(formula,unitCol);  
  
  //подставляем части формулы в шаблон
  pattern = pattern.replace(/Symbol_/g, symbol);
  pattern = pattern.replace(/Value_/g, '=' + value);
  pattern = pattern.replace(/Unit_/g, unit);
  pattern = pattern.replace(/SymbolFormula_/g,symbolFormula);
  pattern = pattern.replace(/ValueFormula_/g, valueFormula);
  pattern = pattern.replace(/UnitFormula_/g, unitFormula);
  
  //улучшаем отображение на сколько это позволяет юникод
  pattern = pattern.split('^2').join('²');
  pattern = pattern.split('^3').join('³');
  pattern = pattern.split('*').join('·');
  pattern = pattern.split('+').join(' + ');
  pattern = pattern.split('-').join(' − ');
  pattern = pattern.split('/').join(' / ');
  pattern = pattern.split('SQRT').join('√');
  pattern = pattern.split('=').join(' = ');
   
  return pattern;
  
}

//функция замены в строке formula адресов ячеек на значения из столбца replaceCol - обозначения параметра (B), значения (C) или размерность (D)
function replaceFormula(formula,replaceCol) {
  return formula.replace( /(([A-Za-z]+\d+))[a-z\d]*/g, function(str) {
    var r=SpreadsheetApp.getActiveSpreadsheet().getRangeByName(str);
    return SpreadsheetApp.getActiveSheet().getRange(r.getRow(),replaceCol).getDisplayValue();} );
}
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.