public void Export(CSVDataSet aSet)
        {
            int count = aSet.Count;

            for (int i = 0; i < count; i++)
            {
                CSVThread thread = aSet[i];

                // find row
                if (iThreadMap.ContainsKey(thread.ThreadId))
                {
                    TThreadMapEntry entry = iThreadMap[thread.ThreadId];

                    Utils.SetValue(entry.iRowIndex, iColumnCounter, iSheetChunkSize, thread.SizeCurrent.ToString());
                    Utils.SetValue(entry.iRowIndex, iColumnCounter, iSheetAlloc, thread.AllocSpaceTotal.ToString());
                    Utils.SetValue(entry.iRowIndex, iColumnCounter, iSheetFree, thread.FreeSpaceTotal.ToString());

                    // Update stats
                    ++entry.iNumberOfMatchingDataSets;

                    // Min & max for each type
                    entry.iRangeChunk.UpdateMin(thread.SizeCurrent);
                    entry.iRangeChunk.UpdateMax(thread.SizeCurrent);
                    entry.iRangeAlloc.UpdateMin(thread.AllocSpaceTotal);
                    entry.iRangeAlloc.UpdateMax(thread.AllocSpaceTotal);
                    entry.iRangeFree.UpdateMin(thread.FreeSpaceTotal);
                    entry.iRangeFree.UpdateMax(thread.FreeSpaceTotal);

                    // Delta for each type
                    long deltaChunk = entry.iLastChunk > 0 ? (thread.SizeCurrent - entry.iLastChunk) : 0;
                    long deltaAlloc = entry.iLastAlloc > 0 ? (thread.AllocSpaceTotal - entry.iLastAlloc) : 0;
                    long deltaFree  = entry.iLastFree > 0 ? (thread.FreeSpaceTotal - entry.iLastFree) : 0;
                    entry.iDeltaChunk += deltaChunk;
                    entry.iDeltaAlloc += deltaAlloc;
                    entry.iDeltaFree  += deltaFree;

                    // Net effect
                    entry.iNetEffectChunk += CSVExcelExporterAllDataSets.NetEffectForDelta(deltaChunk);
                    entry.iNetEffectAlloc += CSVExcelExporterAllDataSets.NetEffectForDelta(deltaAlloc);
                    entry.iNetEffectFree  += CSVExcelExporterAllDataSets.NetEffectForDelta(deltaFree);

                    // Update last values
                    entry.iLastChunk = thread.SizeCurrent;
                    entry.iLastAlloc = thread.AllocSpaceTotal;
                    entry.iLastFree  = thread.FreeSpaceTotal;
                }
                else
                {
                    throw new Exception("Cannot find thread entry for thread named: " + thread.ThreadName);
                }
            }

            ++iColumnCounter;
        }
        private void CalculateDelta(Excel.Worksheet aSheet, TThreadMapEntry.TType aType)
        {
            aSheet.Activate();

            foreach (KeyValuePair <long, TThreadMapEntry> kvp in iThreadMap)
            {
                TThreadMapEntry entry = kvp.Value;
                //
                string formula = entry.Delta(aType);
                Utils.SetValue(entry.iRowIndex, KColumnNumberDelta, aSheet, formula);
            }
        }
        private void CreateSheet(Excel.Worksheet aSheet, string aTitle)
        {
            aSheet.Name = aTitle;

            // Create standard columns
            Utils.SetValue(1, KColumnNumberThreadName, aSheet, "Thread Name");
            Utils.SetValue(1, KColumnNumberChangeFactor, aSheet, "Change Factor");
            Utils.SetValue(1, KColumnNumberDelta, aSheet, "Overall Delta");

            // Set up column formatting
            Utils.FormatColumn(KColumnNumberChangeFactor, aSheet, KColumnNumberFormatChangeFactor);
            Utils.FormatColumn(KColumnNumberDelta, aSheet, KColumnNumberFormatDelta);

            for (int i = 0; i < iDataSetCount; i++)
            {
                int col = i + KColumnNumberCycleFirst;
                Utils.SetValue(1, col, aSheet, string.Format("Cycle {0:d}", i + 1));
                Utils.FormatColumn(col, aSheet, KColumnNumberFormatCycle);
            }

            Utils.MakeBoxedTitleRow(1, KColumnNumberCycleFirst + iDataSetCount, aSheet, 0xFF0000);

            // Add thread names & ids
            int row = 2;

            foreach (KeyValuePair <long, TThreadMapEntry> kvp in iThreadMap)
            {
                TThreadMapEntry entry = kvp.Value;
                Utils.SetValue(row, KColumnNumberThreadName, aSheet, string.Format("[{0:d5}] {1}", kvp.Key, kvp.Value.iThreadName));
                if (entry.iRowIndex == 0)
                {
                    entry.iRowIndex = row;
                }
                ++row;
            }

            // Size columns
            Utils.AutoFitColumn(KColumnNumberThreadName, aSheet);
            Utils.SetColumnWidth(KColumnNumberChangeFactor, aSheet, 15);
            Utils.SetColumnWidth(KColumnNumberDelta, aSheet, 15);
        }
        public CSVExcelExporterAllDataSets(string aOutputFileName, SortedDictionary <long, string> aThreadMap, int aDataSetCount)
        {
            iDataSetCount = aDataSetCount;
            iFileName     = aOutputFileName;

            // Sort the aThreadMap list by thread name, rather than id.
            SortedDictionary <string, TThreadMapEntry> temp = new SortedDictionary <string, TThreadMapEntry>();

            foreach (KeyValuePair <long, string> kvp in aThreadMap)
            {
                TThreadMapEntry entry = new TThreadMapEntry();
                entry.iThreadName = kvp.Value;
                entry.iThreadId   = kvp.Key;
                //
                string mungedName = string.Format("{1} [{0:d5}]", kvp.Key, kvp.Value);
                temp.Add(mungedName, entry);
            }

            // Now build new list, in the right order
            iThreadMap = new Dictionary <long, TThreadMapEntry>(temp.Count + 1);
            foreach (KeyValuePair <string, TThreadMapEntry> kvp in temp)
            {
                iThreadMap.Add(kvp.Value.iThreadId, kvp.Value);
            }

            // Open up excel
            iExcelApp = new Excel.Application();
            if (iExcelApp != null)
            {
                iExcelApp.Visible       = false;
                iExcelApp.DisplayAlerts = false;

                // Prepare sheets
                PrepareWorksheetReadyForData();
            }
            else
            {
                throw new Exception("Microsoft Excel not available");
            }
        }