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 
21 namespace
22 {
23 
24 struct StatisticCalculation {
25  const char* aLabelId;
26  const char* aFormula;
27  const char* aResultRangeName;
28 };
29 
30 StatisticCalculation 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, nullptr }
38 };
39 
40 const char* 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  nullptr
50 };
51 
52 constexpr OUStringLiteral strWildcardRange = u"%RANGE%";
53 
54 OUString 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 
71 void 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 {
102  mxTwoFactorRadio->connect_toggled( LINK( this, ScAnalysisOfVarianceDialog, FactorChanged ) );
103 
104  mxSingleFactorRadio->set_active(true);
105  mxTwoFactorRadio->set_active(false);
106 
107  FactorChanged();
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  const char* 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 {
543  AddressWalkerWriter output(mOutputAddress, pDocShell, mDocument,
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: */
std::unique_ptr< weld::RadioButton > mxTwoFactorRadio
void applyAddress(std::u16string_view aVariable, const ScAddress &aAddress, bool b3D=true)
ScAddress aStart
Definition: address.hxx:500
void writeFormula(const OUString &aFormula)
virtual ~ScAnalysisOfVarianceDialog() override
void writeString(const OUString &aString)
void applyRange(std::u16string_view aVariable, const ScRange &aRange, bool b3D=true)
ScAddress aEnd
Definition: address.hxx:501
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:1142
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
float u
OUString ScResId(const char *pId)
Definition: scdll.cxx:89
void applyRangeList(std::u16string_view aVariable, const ScRangeList &aRangeList, sal_Unicode cDelimiter)
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
ScAnalysisOfVarianceDialog(SfxBindings *pB, SfxChildWindow *pCW, weld::Window *pParent, ScViewData &rViewData)
void applyNumber(std::u16string_view aVariable, sal_Int32 aValue)
void applyString(std::u16string_view aVariable, std::u16string_view 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