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