LibreOffice Module sc (master) 1
AnalysisOfVarianceDialog.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 */
10
11#include <memory>
12#include <string_view>
13
14#include <rangelst.hxx>
15#include <reffact.hxx>
18#include <scresid.hxx>
19#include <strings.hrc>
20
21namespace
22{
23
24struct StatisticCalculation {
25 TranslateId aLabelId;
26 const char* aFormula;
27 const char* aResultRangeName;
28};
29
30StatisticCalculation const lclBasicStatistics[] =
31{
32 { STR_ANOVA_LABEL_GROUPS, nullptr, nullptr },
33 { STRID_CALC_COUNT, "=COUNT(%RANGE%)", "COUNT_RANGE" },
34 { STRID_CALC_SUM, "=SUM(%RANGE%)", "SUM_RANGE" },
35 { STRID_CALC_MEAN, "=AVERAGE(%RANGE%)", "MEAN_RANGE" },
36 { STRID_CALC_VARIANCE, "=VAR(%RANGE%)", "VAR_RANGE" },
37 { {}, nullptr, nullptr }
38};
39
40const TranslateId lclAnovaLabels[] =
41{
42 STR_ANOVA_LABEL_SOURCE_OF_VARIATION,
43 STR_ANOVA_LABEL_SS,
44 STR_ANOVA_LABEL_DF,
45 STR_ANOVA_LABEL_MS,
46 STR_ANOVA_LABEL_F,
47 STR_ANOVA_LABEL_P_VALUE,
48 STR_ANOVA_LABEL_F_CRITICAL,
49 {}
50};
51
52constexpr OUStringLiteral strWildcardRange = u"%RANGE%";
53
54OUString lclCreateMultiParameterFormula(
55 ScRangeList& aRangeList, const OUString& aFormulaTemplate,
56 std::u16string_view aWildcard, const ScDocument& rDocument,
57 const ScAddress::Details& aAddressDetails)
58{
59 OUStringBuffer aResult;
60 for (size_t i = 0; i < aRangeList.size(); i++)
61 {
62 OUString aRangeString(aRangeList[i].Format(rDocument, ScRefFlags::RANGE_ABS_3D, aAddressDetails));
63 OUString aFormulaString = aFormulaTemplate.replaceAll(aWildcard, aRangeString);
64 aResult.append(aFormulaString);
65 if(i != aRangeList.size() - 1) // Not Last
66 aResult.append(";");
67 }
68 return aResult.makeStringAndClear();
69}
70
71void lclMakeSubRangesList(ScRangeList& rRangeList, const ScRange& rInputRange, ScStatisticsInputOutputDialog::GroupedBy aGroupedBy)
72{
73 std::unique_ptr<DataRangeIterator> pIterator;
75 pIterator.reset(new DataRangeByColumnIterator(rInputRange));
76 else
77 pIterator.reset(new DataRangeByRowIterator(rInputRange));
78
79 for( ; pIterator->hasNext(); pIterator->next() )
80 {
81 ScRange aRange = pIterator->get();
82 rRangeList.push_back(aRange);
83 }
84}
85
86}
87
89 SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow,
90 weld::Window* pParent, ScViewData& rViewData )
92 pSfxBindings, pChildWindow, pParent, rViewData,
93 "modules/scalc/ui/analysisofvariancedialog.ui",
94 "AnalysisOfVarianceDialog")
95 , meFactor(SINGLE_FACTOR)
96 , mxAlphaField(m_xBuilder->weld_spin_button("alpha-spin"))
97 , mxSingleFactorRadio(m_xBuilder->weld_radio_button("radio-single-factor"))
98 , mxTwoFactorRadio(m_xBuilder->weld_radio_button("radio-two-factor"))
99 , mxRowsPerSampleField(m_xBuilder->weld_spin_button("rows-per-sample-spin"))
100{
103
104 mxSingleFactorRadio->set_active(true);
105 mxTwoFactorRadio->set_active(false);
106
108}
109
111{
112}
113
115{
117}
118
120{
121 return STR_ANALYSIS_OF_VARIANCE_UNDO_NAME;
122}
123
125{
126 FactorChanged();
127}
128
130{
131 if (mxSingleFactorRadio->get_active())
132 {
133 mxGroupByRowsRadio->set_sensitive(true);
134 mxGroupByColumnsRadio->set_sensitive(true);
135 mxRowsPerSampleField->set_sensitive(false);
137 }
138 else if (mxTwoFactorRadio->get_active())
139 {
140 mxGroupByRowsRadio->set_sensitive(false);
141 mxGroupByColumnsRadio->set_sensitive(false);
142 mxRowsPerSampleField->set_sensitive(false); // Rows per sample not yet implemented
144 }
145}
146
148 const OUString& sFormula, GroupedBy aGroupedBy, ScRange* pResultRange)
149{
150 if (pResultRange != nullptr)
151 pResultRange->aStart = aOutput.current();
152 if (!sFormula.isEmpty())
153 {
154 for (size_t i = 0; i < rRangeList.size(); i++)
155 {
156 ScRange const & rRange = rRangeList[i];
157 aTemplate.setTemplate(sFormula);
158 aTemplate.applyRange(strWildcardRange, rRange);
159 aOutput.writeFormula(aTemplate.getTemplate());
160 if (pResultRange != nullptr)
161 pResultRange->aEnd = aOutput.current();
162 aOutput.nextRow();
163 }
164 }
165 else
166 {
167 TranslateId pLabelId = (aGroupedBy == BY_COLUMN) ? STR_COLUMN_LABEL_TEMPLATE : STR_ROW_LABEL_TEMPLATE;
168 OUString aLabelTemplate(ScResId(pLabelId));
169
170 for (size_t i = 0; i < rRangeList.size(); i++)
171 {
172 aTemplate.setTemplate(aLabelTemplate);
173 aTemplate.applyNumber(u"%NUMBER%", i + 1);
174 aOutput.writeString(aTemplate.getTemplate());
175 if (pResultRange != nullptr)
176 pResultRange->aEnd = aOutput.current();
177 aOutput.nextRow();
178 }
179 }
180}
181
183{
184 output.writeBoldString(ScResId(STR_ANOVA_SINGLE_FACTOR_LABEL));
185 output.newLine();
186
187 double aAlphaValue = mxAlphaField->get_value() / 100.0;
188 output.writeString(ScResId(STR_LABEL_ALPHA));
189 output.nextColumn();
190 output.writeValue(aAlphaValue);
191 aTemplate.autoReplaceAddress("%ALPHA%", output.current());
192 output.newLine();
193 output.newLine();
194
195 // Write labels
196 for(sal_Int32 i = 0; lclBasicStatistics[i].aLabelId; i++)
197 {
198 output.writeString(ScResId(lclBasicStatistics[i].aLabelId));
199 output.nextColumn();
200 }
201 output.newLine();
202
203 // Collect aRangeList
204 ScRangeList aRangeList;
205 lclMakeSubRangesList(aRangeList, mInputRange, mGroupedBy);
206
207 output.push();
208
209 // Write values
210 for(sal_Int32 i = 0; lclBasicStatistics[i].aLabelId; i++)
211 {
212 output.resetRow();
213 ScRange aResultRange;
214 OUString sFormula = OUString::createFromAscii(lclBasicStatistics[i].aFormula);
215 RowColumn(aRangeList, output, aTemplate, sFormula, mGroupedBy, &aResultRange);
216 output.nextColumn();
217 if (lclBasicStatistics[i].aResultRangeName != nullptr)
218 {
219 OUString sResultRangeName = OUString::createFromAscii(lclBasicStatistics[i].aResultRangeName);
220 aTemplate.autoReplaceRange("%" + sResultRangeName + "%", aResultRange);
221 }
222 }
223
224 output.nextRow(); // Blank row
225
226 // Write ANOVA labels
227 output.resetColumn();
228 for(sal_Int32 i = 0; lclAnovaLabels[i]; i++)
229 {
230 output.writeString(ScResId(lclAnovaLabels[i]));
231 output.nextColumn();
232 }
233 output.nextRow();
234
235 aTemplate.autoReplaceRange("%FIRST_COLUMN%", aRangeList[0]);
236
237 // Between Groups
238 {
239 // Label
240 output.resetColumn();
241 output.writeString(ScResId(STR_ANOVA_LABEL_BETWEEN_GROUPS));
242 output.nextColumn();
243
244 // Sum of Squares
245 aTemplate.setTemplate("=SUMPRODUCT(%SUM_RANGE%;%MEAN_RANGE%)-SUM(%SUM_RANGE%)^2/SUM(%COUNT_RANGE%)");
246 aTemplate.autoReplaceAddress("%BETWEEN_SS%", output.current());
247 output.writeFormula(aTemplate.getTemplate());
248 output.nextColumn();
249
250 // Degree of freedom
251 aTemplate.setTemplate("=COUNT(%SUM_RANGE%)-1");
252 aTemplate.autoReplaceAddress("%BETWEEN_DF%", output.current());
253 output.writeFormula(aTemplate.getTemplate());
254 output.nextColumn();
255
256 // MS
257 aTemplate.setTemplate("=%BETWEEN_SS% / %BETWEEN_DF%");
258 aTemplate.autoReplaceAddress("%BETWEEN_MS%", output.current());
259 output.writeFormula(aTemplate.getTemplate());
260 output.nextColumn();
261
262 // F
263 aTemplate.setTemplate("=%BETWEEN_MS% / %WITHIN_MS%");
264 aTemplate.applyAddress(u"%WITHIN_MS%", output.current(-1, 1));
265 aTemplate.autoReplaceAddress("%F_VAL%", output.current());
266 output.writeFormula(aTemplate.getTemplate());
267 output.nextColumn();
268
269 // P-value
270 aTemplate.setTemplate("=FDIST(%F_VAL%; %BETWEEN_DF%; %WITHIN_DF%");
271 aTemplate.applyAddress(u"%WITHIN_DF%", output.current(-3, 1));
272 output.writeFormula(aTemplate.getTemplate());
273 output.nextColumn();
274
275 // F critical
276 aTemplate.setTemplate("=FINV(%ALPHA%; %BETWEEN_DF%; %WITHIN_DF%");
277 aTemplate.applyAddress(u"%WITHIN_DF%", output.current(-4, 1));
278 output.writeFormula(aTemplate.getTemplate());
279 }
280 output.nextRow();
281
282 // Within Groups
283 {
284 // Label
285 output.resetColumn();
286 output.writeString(ScResId(STR_ANOVA_LABEL_WITHIN_GROUPS));
287 output.nextColumn();
288
289 // Sum of Squares
290 OUString aSSPart = lclCreateMultiParameterFormula(aRangeList, "DEVSQ(%RANGE%)", strWildcardRange, mDocument, mAddressDetails);
291 aTemplate.setTemplate("=SUM(%RANGE%)");
292 aTemplate.applyString(strWildcardRange, aSSPart);
293 aTemplate.autoReplaceAddress("%WITHIN_SS%", output.current());
294 output.writeFormula(aTemplate.getTemplate());
295 output.nextColumn();
296
297 // Degree of freedom
298 aTemplate.setTemplate("=SUM(%COUNT_RANGE%)-COUNT(%COUNT_RANGE%)");
299 aTemplate.autoReplaceAddress("%WITHIN_DF%", output.current());
300 output.writeFormula(aTemplate.getTemplate());
301 output.nextColumn();
302
303 // MS
304 aTemplate.setTemplate("=%WITHIN_SS% / %WITHIN_DF%");
305 output.writeFormula(aTemplate.getTemplate());
306 }
307 output.nextRow();
308
309 // Total
310 {
311 // Label
312 output.resetColumn();
313 output.writeString(ScResId(STR_ANOVA_LABEL_TOTAL));
314 output.nextColumn();
315
316 // Sum of Squares
317 aTemplate.setTemplate("=DEVSQ(%RANGE_LIST%)");
318 aTemplate.applyRangeList(u"%RANGE_LIST%", aRangeList, ';');
319 output.writeFormula(aTemplate.getTemplate());
320 output.nextColumn();
321
322 // Degree of freedom
323 aTemplate.setTemplate("=SUM(%COUNT_RANGE%) - 1");
324 output.writeFormula(aTemplate.getTemplate());
325 }
326 output.nextRow();
327}
328
330{
331 output.writeBoldString(ScResId(STR_ANOVA_TWO_FACTOR_LABEL));
332 output.newLine();
333
334 double aAlphaValue = mxAlphaField->get_value() / 100.0;
335 output.writeString("Alpha");
336 output.nextColumn();
337 output.writeValue(aAlphaValue);
338 aTemplate.autoReplaceAddress("%ALPHA%", output.current());
339 output.newLine();
340 output.newLine();
341
342 // Write labels
343 for(sal_Int32 i = 0; lclBasicStatistics[i].aLabelId; i++)
344 {
345 output.writeString(ScResId(lclBasicStatistics[i].aLabelId));
346 output.nextColumn();
347 }
348 output.newLine();
349
350 ScRangeList aColumnRangeList;
351 ScRangeList aRowRangeList;
352
353 lclMakeSubRangesList(aColumnRangeList, mInputRange, BY_COLUMN);
354 lclMakeSubRangesList(aRowRangeList, mInputRange, BY_ROW);
355
356 // Write ColumnX values
357 output.push();
358 for(sal_Int32 i = 0; lclBasicStatistics[i].aLabelId; i++)
359 {
360 output.resetRow();
361 ScRange aResultRange;
362 OUString sFormula = OUString::createFromAscii(lclBasicStatistics[i].aFormula);
363 RowColumn(aColumnRangeList, output, aTemplate, sFormula, BY_COLUMN, &aResultRange);
364 if (lclBasicStatistics[i].aResultRangeName != nullptr)
365 {
366 OUString sResultRangeName = OUString::createFromAscii(lclBasicStatistics[i].aResultRangeName);
367 aTemplate.autoReplaceRange("%" + sResultRangeName + "_COLUMN%", aResultRange);
368 }
369 output.nextColumn();
370 }
371 output.newLine();
372
373 // Write RowX values
374 output.push();
375 for(sal_Int32 i = 0; lclBasicStatistics[i].aLabelId; i++)
376 {
377 output.resetRow();
378 ScRange aResultRange;
379 OUString sFormula = OUString::createFromAscii(lclBasicStatistics[i].aFormula);
380 RowColumn(aRowRangeList, output, aTemplate, sFormula, BY_ROW, &aResultRange);
381
382 if (lclBasicStatistics[i].aResultRangeName != nullptr)
383 {
384 OUString sResultRangeName = OUString::createFromAscii(lclBasicStatistics[i].aResultRangeName);
385 aTemplate.autoReplaceRange("%" + sResultRangeName + "_ROW%", aResultRange);
386 }
387 output.nextColumn();
388 }
389 output.newLine();
390
391 // Write ANOVA labels
392 for(sal_Int32 i = 0; lclAnovaLabels[i]; i++)
393 {
394 output.writeString(ScResId(lclAnovaLabels[i]));
395 output.nextColumn();
396 }
397 output.nextRow();
398
399 // Setup auto-replace strings
400 aTemplate.autoReplaceRange(strWildcardRange, mInputRange);
401 aTemplate.autoReplaceRange("%FIRST_COLUMN%", aColumnRangeList[0]);
402 aTemplate.autoReplaceRange("%FIRST_ROW%", aRowRangeList[0]);
403
404 // Rows
405 {
406 // Label
407 output.resetColumn();
408 output.writeString("Rows");
409 output.nextColumn();
410
411 // Sum of Squares
412 aTemplate.setTemplate("=SUMPRODUCT(%SUM_RANGE_ROW%;%MEAN_RANGE_ROW%) - SUM(%RANGE%)^2 / COUNT(%RANGE%)");
413 aTemplate.autoReplaceAddress("%ROW_SS%", output.current());
414 output.writeFormula(aTemplate.getTemplate());
415 output.nextColumn();
416
417 // Degree of freedom
418 aTemplate.setTemplate("=MAX(%COUNT_RANGE_COLUMN%) - 1");
419 aTemplate.autoReplaceAddress("%ROW_DF%", output.current());
420 output.writeFormula(aTemplate.getTemplate());
421 output.nextColumn();
422
423 // MS
424 aTemplate.setTemplate("=%ROW_SS% / %ROW_DF%");
425 aTemplate.autoReplaceAddress("%MS_ROW%", output.current());
426 output.writeFormula(aTemplate.getTemplate());
427 output.nextColumn();
428
429 // F
430 aTemplate.setTemplate("=%MS_ROW% / %MS_ERROR%");
431 aTemplate.applyAddress(u"%MS_ERROR%", output.current(-1, 2));
432 aTemplate.autoReplaceAddress("%F_ROW%", output.current());
433 output.writeFormula(aTemplate.getTemplate());
434 output.nextColumn();
435
436 // P-value
437 aTemplate.setTemplate("=FDIST(%F_ROW%; %ROW_DF%; %ERROR_DF%");
438 aTemplate.applyAddress(u"%ERROR_DF%", output.current(-3, 2));
439 output.writeFormula(aTemplate.getTemplate());
440 output.nextColumn();
441
442 // F critical
443 aTemplate.setTemplate("=FINV(%ALPHA%; %ROW_DF%; %ERROR_DF%");
444 aTemplate.applyAddress(u"%ERROR_DF%", output.current(-4, 2));
445 output.writeFormula(aTemplate.getTemplate());
446 output.nextColumn();
447 }
448 output.nextRow();
449
450 // Columns
451 {
452 // Label
453 output.resetColumn();
454 output.writeString("Columns");
455 output.nextColumn();
456
457 // Sum of Squares
458 aTemplate.setTemplate("=SUMPRODUCT(%SUM_RANGE_COLUMN%;%MEAN_RANGE_COLUMN%) - SUM(%RANGE%)^2 / COUNT(%RANGE%)");
459 aTemplate.autoReplaceAddress("%COLUMN_SS%", output.current());
460 output.writeFormula(aTemplate.getTemplate());
461 output.nextColumn();
462
463 // Degree of freedom
464 aTemplate.setTemplate("=MAX(%COUNT_RANGE_ROW%) - 1");
465 aTemplate.autoReplaceAddress("%COLUMN_DF%", output.current());
466 output.writeFormula(aTemplate.getTemplate());
467 output.nextColumn();
468
469 // MS
470 aTemplate.setTemplate("=%COLUMN_SS% / %COLUMN_DF%");
471 aTemplate.autoReplaceAddress("%MS_COLUMN%", output.current());
472 output.writeFormula(aTemplate.getTemplate());
473 output.nextColumn();
474
475 // F
476 aTemplate.setTemplate("=%MS_COLUMN% / %MS_ERROR%");
477 aTemplate.applyAddress(u"%MS_ERROR%", output.current(-1, 1));
478 aTemplate.autoReplaceAddress("%F_COLUMN%", output.current());
479 output.writeFormula(aTemplate.getTemplate());
480 output.nextColumn();
481
482 // P-value
483 aTemplate.setTemplate("=FDIST(%F_COLUMN%; %COLUMN_DF%; %ERROR_DF%");
484 aTemplate.applyAddress(u"%ERROR_DF%", output.current(-3, 1));
485 output.writeFormula(aTemplate.getTemplate());
486 output.nextColumn();
487
488 // F critical
489 aTemplate.setTemplate("=FINV(%ALPHA%; %COLUMN_DF%; %ERROR_DF%");
490 aTemplate.applyAddress(u"%ERROR_DF%", output.current(-4, 1));
491 output.writeFormula(aTemplate.getTemplate());
492 output.nextColumn();
493 }
494 output.nextRow();
495
496 // Error
497 {
498 // Label
499 output.resetColumn();
500 output.writeString("Error");
501 output.nextColumn();
502
503 // Sum of Squares
504 aTemplate.setTemplate("=SUMSQ(%RANGE%)+SUM(%RANGE%)^2/COUNT(%RANGE%) - (SUMPRODUCT(%SUM_RANGE_ROW%;%MEAN_RANGE_ROW%) + SUMPRODUCT(%SUM_RANGE_COLUMN%;%MEAN_RANGE_COLUMN%))");
505 aTemplate.autoReplaceAddress("%ERROR_SS%", output.current());
506 output.writeFormula(aTemplate.getTemplate());
507 output.nextColumn();
508
509 // Degree of freedom
510 aTemplate.setTemplate("=%TOTAL_DF% - %ROW_DF% - %COLUMN_DF%");
511 aTemplate.applyAddress(u"%TOTAL_DF%", output.current(0,1));
512 aTemplate.autoReplaceAddress("%ERROR_DF%", output.current());
513 output.writeFormula(aTemplate.getTemplate());
514 output.nextColumn();
515
516 // MS
517 aTemplate.setTemplate("=%ERROR_SS% / %ERROR_DF%");
518 output.writeFormula(aTemplate.getTemplate());
519 }
520 output.nextRow();
521
522 // Total
523 {
524 // Label
525 output.resetColumn();
526 output.writeString("Total");
527 output.nextColumn();
528
529 // Sum of Squares
530 aTemplate.setTemplate("=SUM(%ROW_SS%;%COLUMN_SS%;%ERROR_SS%)");
531 output.writeFormula(aTemplate.getTemplate());
532 output.nextColumn();
533
534 // Degree of freedom
535 aTemplate.setTemplate("=COUNT(%RANGE%)-1");
536 output.writeFormula(aTemplate.getTemplate());
537 output.nextColumn();
538 }
539}
540
542{
545 FormulaTemplate aTemplate(&mDocument);
546
547 if (meFactor == SINGLE_FACTOR)
548 {
549 AnovaSingleFactor(output, aTemplate);
550 }
551 else if (meFactor == TWO_FACTOR)
552 {
553 AnovaTwoFactor(output, aTemplate);
554 }
555
556 return ScRange(output.mMinimumAddress, output.mMaximumAddress);
557}
558
559/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
IMPL_LINK_NOARG(ScAnalysisOfVarianceDialog, FactorChanged, weld::Toggleable &, void)
void writeFormula(const OUString &aFormula)
void writeBoldString(const OUString &aString)
void writeString(const OUString &aString)
ScAddress current(SCCOL aRelativeCol=0, SCROW aRelativeRow=0, SCTAB aRelativeTab=0)
void push(SCCOL aRelativeCol=0, SCROW aRelativeRow=0, SCTAB aRelativeTab=0)
void setTemplate(const OUString &aTemplate)
void applyRangeList(std::u16string_view aVariable, const ScRangeList &aRangeList, sal_Unicode cDelimiter)
void applyRange(std::u16string_view aVariable, const ScRange &aRange, bool b3D=true)
void applyAddress(std::u16string_view aVariable, const ScAddress &aAddress, bool b3D=true)
void autoReplaceAddress(const OUString &aVariable, ScAddress const &aAddress)
void applyNumber(std::u16string_view aVariable, sal_Int32 aValue)
void applyString(std::u16string_view aVariable, std::u16string_view aValue)
void autoReplaceRange(const OUString &aVariable, const ScRange &rRange)
virtual ScRange ApplyOutput(ScDocShell *pDocShell) override
std::unique_ptr< weld::RadioButton > mxTwoFactorRadio
ScAnalysisOfVarianceDialog(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent, ScViewData &rViewData)
void AnovaTwoFactor(AddressWalkerWriter &output, FormulaTemplate &aTemplate)
std::unique_ptr< weld::SpinButton > mxRowsPerSampleField
virtual ~ScAnalysisOfVarianceDialog() override
static void RowColumn(ScRangeList &rRangeList, AddressWalkerWriter &aOutput, FormulaTemplate &aTemplate, const OUString &sFormula, GroupedBy aGroupedBy, ScRange *pResultRange)
std::unique_ptr< weld::RadioButton > mxSingleFactorRadio
std::unique_ptr< weld::SpinButton > mxAlphaField
void AnovaSingleFactor(AddressWalkerWriter &output, FormulaTemplate &aTemplate)
virtual TranslateId GetUndoNameId() override
void push_back(const ScRange &rRange)
Definition: rangelst.cxx:1137
size_t size() const
Definition: rangelst.hxx:89
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
bool DoClose(sal_uInt16 nId)
Definition: anyrefdg.cxx:714
std::unique_ptr< weld::RadioButton > mxGroupByColumnsRadio
std::unique_ptr< weld::RadioButton > mxGroupByRowsRadio
static Grammar mergeToGrammar(const Grammar eGrammar, const AddressConvention eConv)
OString sFormula
float u
int i
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
formula::FormulaGrammar::AddressConvention eConv
Definition: address.hxx:225