Ejemplo n.º 1
0
        private static string RangeToText(ExcelRange range)
        {
            IList <string> items = new List <string>();

            RangeEnumerator enumerator = new RangeEnumerator(range);

            while (enumerator.MoveNext())
            {
                ExcelRange cell = enumerator.Current;
                if (cell != null && !string.IsNullOrWhiteSpace(cell.Text?.ToString()))
                {
                    string text = cell.Text?.ToString();
                    items.Add(text);
                }
            }

            if (items.Count > 0)
            {
                return(string.Join("\n", items));
            }
            else
            {
                return("");
            }
        }
Ejemplo n.º 2
0
            internal Range(ArrayBase <T> thebase, int start, int count, bool forwards, MemoryType memoryType = MemoryType.Normal)
            {
                this.thebase = thebase; stamp = thebase.stamp;
                delta        = forwards ? 1 : -1;

                this.start = start + thebase.offsetField; this.count = count;
                _rangeInternalEnumerator = new RangeEnumerator(thebase, memoryType);
            }
Ejemplo n.º 3
0
                protected override MemorySafeEnumerator <T> Clone()
                {
                    var enumerator = new RangeEnumerator(_rangeEnumeratorArrayBase, MemoryType)
                    {
                        Current = default(T),
                    };

                    return(enumerator);
                }
Ejemplo n.º 4
0
 // Position the iterator at the first cell that follows "target", i.e. the
 // first cell such that RangeMin > target.RangeMax.
 public void SeekBeyond(RangeEnumerator target)
 {
     _it.SetPosition(_index.SeekCell(target.RangeMax.Next()).pos);
     if (!_it.Done() && _it.Id.RangeMin() <= target.RangeMax)
     {
         _it.MoveNext();
     }
     Refresh();
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Индексы элементов исходной матрицы, которые принадлежат ячейке разбитой матрицы с индексом index
        /// </summary>
        /// <param name="index">Индекс ячейки разбитой матрицы</param>
        /// <returns>Перечисление элементов исходной матрицы, которые принадлежат ячейке разбитой матрицы с индексом index</returns>
        public IEnumerable <IIndex> CellElements(IIndex index)
        {
            int[] low  = new int[index.Dimensions];
            int[] high = new int[index.Dimensions];

            for (int i = 0; i < index.Dimensions; i++)
            {
                low[i]  = CellLow(index[i], i);
                high[i] = CellHigh(index[i], i);
            }

            return(RangeEnumerator.Indexes(low, high));
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Given two iterators positioned such that ai.id().Contains(bi.id()),
 /// visits all crossings between edges of A and B that intersect a.id().
 /// Terminates early and returns false if visitor_ returns false.
 /// Advances both iterators past ai.id().
 /// </summary>
 public bool VisitCrossings(RangeEnumerator ai, RangeEnumerator bi)
 {
     System.Diagnostics.Debug.Assert(ai.Id.Contains(bi.Id));
     if (ai.Cell.NumEdges() == 0)
     {
         // Skip over the cells of B using binary search.
         bi.SeekBeyond(ai);
     }
     else
     {
         // If ai.id() intersects many edges of B, then it is faster to use
         // S2CrossingEdgeQuery to narrow down the candidates.  But if it
         // intersects only a few edges, it is faster to check all the crossings
         // directly.  We handle this by advancing "bi" and keeping track of how
         // many edges we would need to test.
         int b_edges = 0;
         b_cells_.Clear();
         do
         {
             int cell_edges = bi.Cell.NumEdges();
             if (cell_edges > 0)
             {
                 b_edges += cell_edges;
                 if (b_edges >= kEdgeQueryMinEdges)
                 {
                     // There are too many edges, so use an S2CrossingEdgeQuery.
                     if (!VisitSubcellCrossings(ai.Cell, ai.Id))
                     {
                         return(false);
                     }
                     bi.SeekBeyond(ai);
                     return(true);
                 }
                 b_cells_.Add(bi.Cell);
             }
             bi.MoveNext();
         } while (bi.Id <= ai.RangeMax);
         if (b_cells_.Any())
         {
             // Test all the edge crossings directly.
             GetShapeEdges(a_index_, ai.Cell, a_shape_edges_);
             GetShapeEdges(b_index_, b_cells_, b_shape_edges_);
             if (!VisitEdgesEdgesCrossings(a_shape_edges_, b_shape_edges_))
             {
                 return(false);
             }
         }
     }
     ai.MoveNext();
     return(true);
 }
        public QueryOperatorEnumerator <int, int>[] GetPartitions(int partitionCount)
        {
            int num          = this.m_count / partitionCount;
            int num2         = this.m_count % partitionCount;
            int initialIndex = 0;

            QueryOperatorEnumerator <int, int>[] enumeratorArray = new QueryOperatorEnumerator <int, int> [partitionCount];
            for (int i = 0; i < partitionCount; i++)
            {
                int count = (i < num2) ? (num + 1) : num;
                enumeratorArray[i] = new RangeEnumerator(this.m_from + initialIndex, count, initialIndex);
                initialIndex      += count;
            }
            return(enumeratorArray);
        }
Ejemplo n.º 8
0
 // Position the iterator at the first cell that overlaps or follows
 // "target", i.e. such that RangeMax >= target.RangeMin.
 public void SeekTo(RangeEnumerator target)
 {
     _it.SetPosition(_index.SeekCell(target.RangeMin).pos);
     // If the current cell does not overlap "target", it is possible that the
     // previous cell is the one we are looking for.  This can only happen when
     // the previous cell contains "target" but has a smaller S2CellId.
     if (_it.Done() || _it.Id.RangeMin() > target.RangeMax)
     {
         if (_it.MovePrevious() && _it.Id.RangeMax() < target.Id)
         {
             _it.MoveNext();
         }
     }
     Refresh();
 }
Ejemplo n.º 9
0
        //-----------------------------------------------------------------------------------
        // Retrieves 'count' partitions, each of which uses a non-overlapping set of indices.
        //

        public QueryOperatorEnumerator <int, int>[] GetPartitions(int partitionCount)
        {
            // Calculate a stride size, avoiding overflow if _count is large
            int stride = _count / partitionCount;
            int biggerPartitionCount = _count % partitionCount;

            // Create individual partitions, carefully avoiding overflow
            int doneCount = 0;

            QueryOperatorEnumerator <int, int>[] partitions = new QueryOperatorEnumerator <int, int> [partitionCount];
            for (int i = 0; i < partitionCount; i++)
            {
                int partitionSize = (i < biggerPartitionCount) ? stride + 1 : stride;
                partitions[i] = new RangeEnumerator(
                    unchecked (_from + doneCount),
                    partitionSize,
                    doneCount);
                doneCount += partitionSize;
            }

            return(partitions);
        }
Ejemplo n.º 10
0
        public static void Execute(OfficeApps apps, Input input)
        {
            if (Flow.Interrupted)
            {
                return;
            }

            Log.Info("Executing Script");

            Log.Debug("Target: " + input.Workbook.FullName);
            Log.Debug("Template: " + input.Template.Name);

            Log.Debug("Checking which cells are numerical:");
            Log.PushIndent();

            var fullEnumerator = new RangeEnumerator(input.Template.UsedRange);

            bool[,] mask = new bool[fullEnumerator.Height, fullEnumerator.Width];

            Progress.Init(Log.Debug);
            Progress.Reset();

            while (fullEnumerator.MoveNext())
            {
                Progress.Report(fullEnumerator.Progress);

                ExcelRange cell = fullEnumerator.Current;

                if (Flow.Interrupted)
                {
                    break;
                }

                bool numeric = ExcelHelper.IsCellAnywhereNumeric(apps, cell.Row, cell.Column);
                mask[fullEnumerator.RowIndex, fullEnumerator.ColumnIndex] = numeric;
            }

            Progress.Complete();
            fullEnumerator.Dispose();

            Log.PopIndent();

            if (Flow.Interrupted)
            {
                return;
            }

            Log.Debug("Creating summary sheets:");

            // Strange to double these I know, but it makes it easier to keep track of
            // indents with interruptions this way.
            Log.PushIndent();
            Log.PushIndent();

            foreach (string formula in input.Formulae)
            {
                string name = ExcelHelper.CreateUniqueWorksheetName(input.Workbook, formula);

                Log.PopIndent();
                Log.Debug($"Creating sheet \"{name}\":");
                Log.PushIndent();

                if (Flow.Interrupted)
                {
                    break;
                }

                input.Template.Copy(After: input.Workbook.Sheets[apps.Excel.Sheets.Count]);

                if (Flow.Interrupted)
                {
                    break;
                }

                Worksheet newSheet = (Worksheet)input.Workbook.ActiveSheet;
                newSheet.Name = name;

                var maskedEnumerator = new RangeEnumerator(newSheet.UsedRange);
                maskedEnumerator.ApplyMask(mask);
                Progress.Reset();

                while (maskedEnumerator.MoveNext())
                {
                    Progress.Report(maskedEnumerator.Progress);

                    ExcelRange cell = maskedEnumerator.Current;

                    if (Flow.Interrupted)
                    {
                        break;
                    }

                    string range       = $"'{input.SheetReference}'!{cell.Address}";
                    string formulaText = $"={formula}({range})";

                    cell.Value = formulaText;
                }

                Progress.Complete();
                maskedEnumerator.Dispose();

                if (Flow.Interrupted)
                {
                    break;
                }
            }

            Log.PopIndent();
            Log.PopIndent();

            if (Flow.Interrupted)
            {
                return;
            }

            Log.Debug($"Saving {input.Workbook.FullName}");
            input.Workbook.Save();
            Log.Success("Script complete");
        }
Ejemplo n.º 11
0
        public static void Execute(OfficeApps apps, Input input)
        {
            if (Flow.Interrupted)
            {
                return;
            }

            Log.Info("Executing Script");

            input.Template.Copy(After: input.Workbook.Sheets[apps.Excel.Sheets.Count]);

            if (Flow.Interrupted)
            {
                return;
            }

            Worksheet active = (Worksheet)apps.Excel.ActiveSheet;

            active.Name = ExcelHelper.CreateUniqueWorksheetName(input.Workbook, "Summary");

            if (Flow.Interrupted)
            {
                return;
            }

            ExcelHelper.TryParseWorksheetRange(out IEnumerable <Worksheet> worksheets, input.Workbook, input.SheetReference,
                                               compareWords: true, verbrose: true);

            if (Flow.Interrupted)
            {
                return;
            }

            RangeEnumerator enumerator = new RangeEnumerator(active.UsedRange);

            Progress.Init(Log.Debug);
            Progress.Reset();

            while (enumerator.MoveNext())
            {
                if (Flow.Interrupted)
                {
                    return;
                }

                ExcelRange cell = enumerator.Current;
                string     text = cell.Value?.ToString();
                if (text == null)
                {
                    continue;
                }

                string command = text.Trim().ToLower();

                string referencePattern = "\\$\\s*([\\d\\w]+)\\s*\\$";

                if (command == "$sheetname$")
                {
                    int i = 0;
                    foreach (Worksheet sheet in worksheets)
                    {
                        if (Flow.Interrupted)
                        {
                            return;
                        }

                        // Note the self: .Cells[i,j] is 1-based, not 0-based!
                        ExcelRange recordCell = (ExcelRange)active.Cells[1 + enumerator.RowIndex, 1 + enumerator.ColumnIndex + i];
                        recordCell.Value = sheet.Name;
                        i++;
                    }
                }
                else
                {
                    Match match = Regex.Match(command.ToUpper(), referencePattern);
                    if (match.Success)
                    {
                        string reference = match.Groups[1].Value;

                        try
                        {
                            int i = 0;
                            foreach (Worksheet sheet in worksheets)
                            {
                                if (Flow.Interrupted)
                                {
                                    return;
                                }

                                ExcelRange sourceCell      = (ExcelRange)sheet.Range[reference];
                                ExcelRange destinationCell = (ExcelRange)active.Cells[1 + enumerator.RowIndex, 1 + enumerator.ColumnIndex + i];

                                destinationCell.Value = sourceCell.Value?.ToString();
                                i++;
                            }
                        }
                        catch (Exception e)
                        {
                            Log.Warning($"Failed to apply reference {reference}");
                            Log.Debug("(Is it a valid reference?)");

                            if (AppHelper.DebugFlag)
                            {
                                Log.Debug("Note to self:", e);
                            }
                        }
                    }
                }

                Progress.Report(enumerator.Progress);
            }

            if (Flow.Interrupted)
            {
                return;
            }

            Progress.Complete();

            Log.Debug($"Saving {input.Workbook.FullName}");
            input.Workbook.Save();
            Log.Success("Script complete");
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Like the above, but visits all pairs of crossing edges where one edge comes
        /// from each S2ShapeIndex.
        ///
        /// CAVEAT: Crossings may be visited more than once.
        /// </summary>
        public static bool VisitCrossingEdgePairs(S2ShapeIndex a_index, S2ShapeIndex b_index, CrossingType type, EdgePairVisitor visitor)
        {
            // We look for S2CellId ranges where the indexes of A and B overlap, and
            // then test those edges for crossings.

            // TODO(ericv): Use brute force if the total number of edges is small enough
            // (using a larger threshold if the S2ShapeIndex is not constructed yet).
            var ai = new RangeEnumerator(a_index);
            var bi = new RangeEnumerator(b_index);
            var ab = new IndexCrosser(a_index, b_index, type, visitor, false);  // Tests A against B
            var ba = new IndexCrosser(b_index, a_index, type, visitor, true);   // Tests B against A

            while (!ai.Done() || !bi.Done())
            {
                if (ai.RangeMax < bi.RangeMin)
                {
                    // The A and B cells don't overlap, and A precedes B.
                    ai.SeekTo(bi);
                }
                else if (bi.RangeMax < ai.RangeMin)
                {
                    // The A and B cells don't overlap, and B precedes A.
                    bi.SeekTo(ai);
                }
                else
                {
                    // One cell contains the other.  Determine which cell is larger.
                    var ab_relation = ai.Id.LowestOnBit() - bi.Id.LowestOnBit();
                    if (ab_relation > 0)
                    {
                        // A's index cell is larger.
                        if (!ab.VisitCrossings(ai, bi))
                        {
                            return(false);
                        }
                    }
                    else if (ab_relation < 0)
                    {
                        // B's index cell is larger.
                        if (!ba.VisitCrossings(bi, ai))
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        // The A and B cells are the same.
                        if (ai.Cell.NumEdges() > 0 && bi.Cell.NumEdges() > 0)
                        {
                            if (!ab.VisitCellCellCrossings(ai.Cell, bi.Cell))
                            {
                                return(false);
                            }
                        }
                        ai.MoveNext();
                        bi.MoveNext();
                    }
                }
            }
            return(true);
        }