MCPcopy Create free account
hub / github.com/QtExcel/QXlsx / parse_function

Method parse_function

FormulaDump/mini_formula_evaluator.cpp:181–262  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

179}
180
181QVariant mini_formula_evaluator_t::parse_function(const QString& base_sheet, const QString& func)
182{
183 static const QRegularExpression re(R"(^([A-Za-z_][A-Za-z0-9_]*)\((.*)\)$)");
184 const auto m = re.match(func.trimmed());
185 if (!m.hasMatch()) return {};
186
187 const QString name = m.captured(1).toUpper();
188 const QString args_str = m.captured(2).trimmed();
189 const QStringList args = split_args_top_level(args_str);
190
191 auto eval_arg_number = [&](const QString& a) -> double {
192 const QVariant v = eval(base_sheet, a);
193 return to_double_or_nan(v);
194 };
195
196 if (name == "SUM" || name == "AVERAGE" || name == "MIN" || name == "MAX") {
197 double acc = 0.0;
198 double mn = std::numeric_limits<double>::infinity();
199 double mx = -std::numeric_limits<double>::infinity();
200 int cnt = 0;
201
202 auto consume_value = [&](double d) {
203 if (std::isnan(d)) return;
204 acc += d;
205 mn = std::min(mn, d);
206 mx = std::max(mx, d);
207 ++cnt;
208 };
209
210 for (const QString& a0 : args) {
211 const QString a = a0.trimmed();
212
213 // range: A1:B3 or Sheet1!A1:B3
214 static const QRegularExpression re_sheet(R"(^([^!]+)!(.+)$)");
215 static const QRegularExpression re_range(R"(^(\$?[A-Za-z]+\$?\d+):(\$?[A-Za-z]+\$?\d+)$)");
216
217 QString sheet = base_sheet;
218 QString range = a;
219
220 const auto ms = re_sheet.match(a);
221 if (ms.hasMatch()) {
222 sheet = ms.captured(1).trimmed();
223 range = ms.captured(2).trimmed();
224 }
225
226 const auto mr = re_range.match(range);
227 if (mr.hasMatch()) {
228 int r1=0,c1=0,r2=0,c2=0;
229 if (!try_parse_cell_ref(mr.captured(1), r1, c1)) continue;
230 if (!try_parse_cell_ref(mr.captured(2), r2, c2)) continue;
231 if (r1 > r2) std::swap(r1, r2);
232 if (c1 > c2) std::swap(c1, c2);
233 for (int r = r1; r <= r2; ++r) {
234 for (int c = c1; c <= c2; ++c) {
235 consume_value(to_double_or_nan(eval_cell(sheet, r, c)));
236 }
237 }
238 continue;

Callers

nothing calls this directly

Calls 1

split_args_top_levelFunction · 0.85

Tested by

no test coverage detected