需要构建一个在 Excel 中使用的 UDF,使用 Excel DNA,以呈现以锯齿状方式特别排序的结果,使用 C# 的 IComparer 我很惊讶,因为我没有得到预期的结果。
虽然在控制台应用程序中使用相同的代码,但结果运行良好,使用的代码是:
using System;
using System.Linq;
using System.Collections.Generic;
namespace Clxn
{
public static class fComparer
{
static void Main(string[] args)
{
object[,] MainRange =
{
{ "c", "E", "B" },
{ "b", "A", "B" },
{ "A", "D", "D" },
{ "F", "D", "C" }
};
int Cntr = 0;
object[] SortingKey = (from object x in MainRange select x).ToArray();
object[,] Rxlt = new object[SortingKey.Length, MainRange.GetLength(1) + 1];
for (int xCol = 0; xCol < Rxlt.GetLength(1); xCol++)
{
Cntr = 0;
for (int xRow = 0; xRow < Rxlt.GetLength(0); xRow++)
{
if (xCol == 0) { Rxlt[xRow, 0] = SortingKey.OrderBy(x => x, new fxl_ComparerObjects()).ToArray()[(Rxlt.GetLength(0) * (xCol)) + xRow]; }
else
{
object[] OrderedSlice = SlicedColumn(MainRange, xCol - 1).ToArray().OrderBy(f => f, new fxl_ComparerObjects()).ToArray();
if (Rxlt[xRow, 0] == OrderedSlice[Cntr]) { Rxlt[xRow, xCol] = OrderedSlice[Cntr]; Cntr++; }
}
if (Cntr >= MainRange.GetLength(0)) Cntr = 0;
}
}
for (int xRow = 0; xRow < Rxlt.GetLength(0); xRow++)
{
for (int xCol = 0; xCol < Rxlt.GetLength(1); xCol++) { Console.Write(Rxlt[xRow, xCol] + "\t"); }
Console.WriteLine("");
}
}
internal static IEnumerable<T> SlicedColumn<T>(this T[,] array, int column)
{
for (var i = array.GetLowerBound(0); i <= array.GetUpperBound(0); i++) { yield return array[i, column]; }
}
internal class fxl_ComparerObjects : IComparer<object>
{
public int SorterIndex { get; set; }
public int Compare(object x, object y)
{
double xVal, yVal;
var xIsVal = double.TryParse(x.ToString(), out xVal);
var yIsVal = double.TryParse(y.ToString(), out yVal);
if (xIsVal && yIsVal) return xVal.CompareTo(yVal);
if (!xIsVal && !yIsVal) return x.ToString().CompareTo(y.ToString());
if (xIsVal) return -1;
return 1;
}
}
internal class fxl_ComparerArrays : IComparer<object[]>
{
public int SorterIndex { get; set; }
public int Compare(object[] x, object[] y)
{
double xVal, yVal;
bool xIsNumber = double.TryParse(x.GetValue(SorterIndex - 1).ToString(), out xVal);
bool yIsNumber = double.TryParse(y.GetValue(SorterIndex - 1).ToString(), out yVal);
if (xIsNumber && yIsNumber) return xVal.CompareTo(yVal);
else if (!xIsNumber && !yIsNumber) return x.GetValue(SorterIndex - 1).ToString().CompareTo(y.GetValue(SorterIndex - 1).ToString());
else if (xIsNumber) return -1;
else return 1;
}
}
}
}
,在Console App的情况下,根据需要和预期,导致首先生成一个排序的键列,然后从双维数组中每个相关列的值仅在匹配时放置,在第一次匹配时,即:
然而,令人惊讶的是,用于 Excel 的相同代码导致结果如下:
即尽管使用相同的代码,但值被分散以填充每一列和每一行,但完全相同。
在调试时,我也发现了一些值,虽然相同,但根据剪辑如下,声明不相等,尽管两个数组变量的第一个都是“A”:
将光标悬停在如下语句上,也发现结果不相等,即生成false:
这背后的原因可能是什么?
提前感谢您的所有贡献。