一般做OA类管理系统,经常涉及到“组织架构”的概念,那么像这种有上下层级关系的数据一般会做成树形菜单的方式显示,底层代码必定会用到递归算法。这篇随笔的目的就是要谈谈除了用树形菜单来显示这种上下层级关系的数据,还有其他的显示方式吗?答案是有的,例如即将要谈到的二维表显示方式,同时也是本随笔的核心内容。

  首先来看二维表的显示效果图:

如果看到这里,你觉得这就是你想要的显示效果,或者对此比较感兴趣。请接着往下看的实现步骤:

1.取出所有的数据临时保存到DataTable中,即内存中,拼html时直接查DataTable中的数据,不用去反复读取数据库,提高效率;

2.根据节点编号获取该节点下所有的末端子节点编号,因为末端子节点的个数就决定了<table>的行数;

3.将查到的末端子节点编号的所有父节点编号也查出来,拼接起来,就知道了<table>的每行的列数;

4.对节点的编号进行排序,这样可以把每列下的相同行的节点编号集中在一起,方便后面的合并单元格;

5.遍历行和列,合并每列相同行的单元格;

6.最后一步,拼接空白的列。

如下是具体代码实现过程:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Text; /// <summary>
///KpiTable 的摘要说明
/// </summary>
public class KpiTable
{
DBUtility.SQLHelper sqlhelper = new DBUtility.SQLHelper();
public string GetKpiTable(string kpino, string businessno, string tenderno)
{
//1.取出所有的数据临时保存到dt2,即内存中,拼html时直接查dt2中的数据,不用去反复读取数据库,提高效率
DataTable dt2 = new DataTable();
{
DataSet ds = new DataSet();
int i = sqlhelper.RunSQL(string.Format("select count(1) from sys.objects where name = 'KpiValue{0}'", businessno));
if (string.IsNullOrEmpty(tenderno) || i<)//如果有标段编号就要把KpiValueXXX表里的KpiValue1查出来显示
{
sqlhelper.RunSQL(string.Format(@"select KpiNo,KpiName,KpiInfo,ISNULL(KpiParentNo,0) KpiParentNo,KpiWeight,0 KpiValue1,'' KpiMethod,'' KpiSampleType,'' KpiRule,'' KpiCriterion,'' KpiAreaRule,'' KpiSampleRule from KpiTree{0}
union all select KpiNo,KpiName,KpiInfo,ISNULL(KpiParentNo,0) KpiParentNo,KpiWeight,0 KpiValue1,KpiMethod,KpiSampleType,KpiRule,KpiCriterion,KpiAreaRule,KpiSampleRule from Kpi{0}",businessno), ref ds);
}
else
{
sqlhelper.RunSQL(string.Format(@"select * from (
select KpiNo,KpiName,KpiInfo,ISNULL(KpiParentNo,0) KpiParentNo,KpiWeight,0 KpiValue1,'' KpiMethod,'' KpiSampleType,'' KpiRule,'' KpiCriterion,'' KpiAreaRule,'' KpiSampleRule from KpiTree{0}
union all select KpiNo,KpiName,KpiInfo,ISNULL(KpiParentNo,0) KpiParentNo,KpiWeight,0 KpiValue1,KpiMethod,KpiSampleType,KpiRule,KpiCriterion,KpiAreaRule,KpiSampleRule from Kpi{0}
) a left join KpiValue{0} b on a.kpino = b.kpino and TenderNo='{1}'", businessno, tenderno), ref ds);
}
dt2 = ds.Tables[];
}
//2.根据节点编号获取该节点下所有的末端子节点编号,因为末端子节点的个数就决定了table的行数
DataTable dt = new DataTable();
{
DataSet ds = new DataSet();
if (string.IsNullOrEmpty(kpino) || kpino == "")
{
sqlhelper.RunSQL(string.Format(@"select kpino from (select kpino from kpitree{0} union all select kpino from Kpi{0}) t where kpino not in (select isnull(KpiParentNo,0) from (select KpiParentNo from kpitree{0} union all select KpiParentNo from Kpi{0}) t)", businessno), ref ds);
}
else
{
string endKpiNo = RecursionEndKpiNo(dt2, kpino).Trim(',');
endKpiNo = endKpiNo == "" ? "" : endKpiNo;
string kpinos = string.Empty;
foreach (string str in endKpiNo.Split(',')) { kpinos += "'" + str + "',"; }
kpinos = kpinos.Trim(',');
sqlhelper.RunSQL(string.Format(@"select kpino from (select kpino from kpitree{0} union all select kpino from Kpi{0}) t where kpino not in (select isnull(KpiParentNo,0) from (select KpiParentNo from kpitree{0} union all select KpiParentNo from Kpi{0}) t) and kpino in ({1})", businessno, kpinos), ref ds);
}
dt = ds.Tables[];
}
//3.将查到的末端子节点编号的所有父节点编号也查出来,拼接起来,就知道了table的每行的列数
foreach (DataRow row in dt.Rows)
{
row["kpino"] = Recursion(dt2, row["kpino"]);
}
//4.对编号进行排序,这样可以把每列下的相同行的节点编号集中在一起,方便后面的合并单元格
var drArray = dt.Select("1=1", "kpino");
//5.限制输出kpino之前的父节点信息
foreach (DataRow row in drArray)
{
int index = row["kpino"].ToString().IndexOf(kpino);
if (index > -)
{
row["kpino"] = row["kpino"].ToString().Substring(index);
}
}
//6.遍历行和列
int maxCount = GetMaxCount(drArray);
StringBuilder sbJson = new StringBuilder();
for (int i = ; i < drArray.Length; i++)
{
DataRow row = drArray[i];
sbJson.Append("<tr>");
var kpinoArray = row["kpino"].ToString().Trim(',').Split(',');
int kpinoArrayLenth = kpinoArray.Length;
for (int j = ; j < kpinoArrayLenth; j++)
{
string str = kpinoArray[j];
if (str != "")
{
var dr = dt2.Select("kpino='" + str + "'");
//合并每列相同行的单元格
if (dr.Length > && !EqualUpColumnValue(i, j, drArray))
{
double kpiWeight = GetKpiWeight(dt2, str);
double kpiValue = GetKpiValue(dt2, str);
string kpiValueStr = string.IsNullOrEmpty(tenderno) ? "" : "[" + (kpiValue * kpiWeight).ToString("0.00") + "]";
string kpiDes = GetKpiDes(dt2, str);
sbJson.Append(string.Format("<td rowspan='{0}'>{1}({2}%){3}{4}</td>", GetColspan(i, j, drArray), dr[]["kpiname"], (kpiWeight * ).ToString("0.00"), kpiValueStr, kpiDes));
}
}
}
//拼接空白的列
for (int j = ; j < maxCount - kpinoArrayLenth; j++)
{
sbJson.Append("<td></td>");
}
sbJson.Append("</tr>");
}
return "<table id='kpitable' border='1px'>" + sbJson.ToString() + "</table>";
} private string RecursionEndKpiNo(DataTable dt, object parentId)
{
StringBuilder sbJson = new StringBuilder(); DataRow[] rows = dt.Select(string.Format("KpiParentNo = '" + parentId + "'"));
if (rows.Length > )
{
foreach (DataRow row in rows)
{
string str = RecursionEndKpiNo(dt, row["kpino"]);
sbJson.Append("" + row["kpino"] + "," + str);
}
}
return sbJson.ToString();
}
private bool IsChild(DataTable dt, string parentId)
{
DataRow[] rows = dt.Select(string.Format("KpiParentNo = '" + parentId + "'"));
if (rows.Length > )
{
return true;
}
else
{
return false;
}
} private string Recursion(DataTable dt, object parentId)
{
StringBuilder sbJson = new StringBuilder(); DataRow[] rows = dt.Select("kpino = '" + parentId + "'");
if (rows.Length > )
{
if (rows[]["KpiParentNo"].ToString() == "" || rows[]["KpiParentNo"].ToString() == "")
{
sbJson.Append("0,");
}
else
{
sbJson.Append(Recursion(dt, rows[]["KpiParentNo"]));
}
}
sbJson.Append(parentId.ToString() + ",");
return sbJson.ToString();
}
private int GetMaxCount(DataRow[] drArray)
{
int temp = ;
foreach (DataRow row in drArray)
{
int count = row["kpino"].ToString().Trim(',').Split(',').Length;
if (count > temp)
{
temp = count;
}
}
return temp;
}
private bool EqualUpColumnValue(int rowIndex, int colIndex, DataRow[] drArray)
{
if (rowIndex == )
{
return false;
} string[] kpinoArray = drArray[rowIndex - ]["kpino"].ToString().Trim(',').Split(',');
if (kpinoArray.Length > colIndex)
{
string upColumnValue = drArray[rowIndex]["kpino"].ToString().Trim(',').Split(',')[colIndex];
if (upColumnValue == kpinoArray[colIndex])
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
private int GetColspan(int rowIndex, int colIndex, DataRow[] drArray)
{
int colspan = ;
string[] kpinoArray = drArray[rowIndex]["kpino"].ToString().Trim(',').Split(','); while (rowIndex < drArray.Length - )
{
string[] kpinoArray2 = drArray[rowIndex + ]["kpino"].ToString().Trim(',').Split(',');
if (kpinoArray2.Length > colIndex)
{
if (kpinoArray[colIndex] == kpinoArray2[colIndex])
{
colspan++;
}
else
{
break;
}
}
else
{
break;
}
rowIndex++;
}
return colspan;
}
private double GetKpiWeight(DataTable dt, string kpino)
{
double kpiWeight = ;
var drArray = dt.Select("kpino='" + kpino + "'");
if (drArray.Length > )
{
string kpiParentNo = drArray[]["KpiParentNo"].ToString();
double kpino_KpiWeight = Convert.ToDouble(drArray[]["KpiWeight"]);
drArray = dt.Select("KpiParentNo='" + kpiParentNo + "'");
if (drArray.Length > )
{
double result = ;
foreach (DataRow row in drArray)
{
result += Convert.ToDouble(row["KpiWeight"]);
}
kpiWeight = (kpino_KpiWeight / result);
}
}
return kpiWeight;
}
private double GetKpiValue(DataTable dt, string kpino)
{
var drArray = dt.Select(string.Format("kpino='{0}'",kpino));
if (drArray.Length>)
{
return Convert.ToDouble(drArray[]["KpiValue1"]);
}
return ;
}
private string GetKpiDes(DataTable dt, string kpino)
{
string des = string.Empty;
var drArray = dt.Select(string.Format("kpino='{0}'",kpino));
if (drArray.Length>)
{
string KpiMethod = drArray[]["KpiMethod"].ToString();
string KpiSampleType = drArray[]["KpiSampleType"].ToString();
string KpiRule = drArray[]["KpiRule"].ToString();
string KpiCriterion = drArray[]["KpiCriterion"].ToString();
string KpiAreaRule = drArray[]["KpiAreaRule"].ToString();
string KpiSampleRule = drArray[]["KpiSampleRule"].ToString(); //表格样式
if (!string.IsNullOrEmpty(KpiMethod))
{
//des += "<table id='kpitabledes'>";
//des += "<tr><td>计算方法:</td><td>" + KpiMethod +"</td></tr>";
//des += "<tr><td>采样类别:</td><td>" + KpiSampleType + "</td></tr>";
//des += "<tr><td>评价标准:</td><td>" + KpiRule + "</td></tr>";
//des += "<tr><td>规范要点:</td><td>" + KpiCriterion + "</td></tr>";
//des += "<tr><td>测区规则:</td><td>" + KpiAreaRule + "</td></tr>";
//des += "<tr><td>测点规则:</td><td>" + KpiSampleRule + "</td></tr>";
//des += "</table>";
} //换行样式
//if (!string.IsNullOrEmpty(KpiMethod)) { des += "<br />计算方法:" + KpiMethod; }
//if (!string.IsNullOrEmpty(KpiSampleType)) { des += "<br />采样类别:" + KpiSampleType; }
//if (!string.IsNullOrEmpty(KpiRule)) { des += "<br />评价标准:" + KpiRule; }
//if (!string.IsNullOrEmpty(KpiCriterion)) { des += "<br />规范要点:" + KpiCriterion; }
//if (!string.IsNullOrEmpty(KpiAreaRule)) { des += "<br />测区规则:" + KpiAreaRule; }
//if (!string.IsNullOrEmpty(KpiSampleRule)) { des += "<br />测点规则:" + KpiSampleRule; }
}
return des;
} }

以及需要用到的表(sql脚本):

 USE [Evaluation]
GO
/****** Object: Table [dbo].[Kpi] Script Date: 2016/3/25 16:06:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Kpi](
[KpiNo] [nvarchar](50) NOT NULL,
[KpiName] [nvarchar](50) NULL,
[KpiInfo] [nvarchar](100) NULL,
[KpiParentNo] [nvarchar](50) NULL,
[KpiMethod] [nvarchar](50) NULL,
[KpiWeight] [decimal](18, 2) NULL,
[KpiRule] [nvarchar](100) NULL,
[KpiCriterion] [nvarchar](100) NULL,
[KpiAreaRule] [nvarchar](100) NULL,
[KpiSampleRule] [nvarchar](100) NULL,
[KpiAreaNum] [int] NOT NULL,
[KpiSampleNum] [int] NOT NULL,
[KpiMinValue] [decimal](18, 2) NULL,
[KpiMaxValue] [decimal](18, 2) NULL,
[KpiOffset] [decimal](18, 2) NULL,
[KpiReferenceVal] [decimal](18, 2) NULL,
[KpiValueType] [nvarchar](50) NULL,
[KpiFormula] [nvarchar](50) NULL,
[KpiFormulaRule] [nvarchar](100) NULL,
[KpiMemo] [nvarchar](100) NULL,
[KpiGoodMinValue] [decimal](18, 2) NULL,
[KpiGoodMaxValue] [decimal](18, 2) NULL,
[KpiGoodMethod] [nvarchar](50) NULL,
[KpiGoodOffset] [decimal](18, 2) NULL,
[KpiSampleType] [nvarchar](50) NULL,
[IsDLT] [smallint] NULL,
[CrtDate] [datetime] NULL,
[CrtUser] [nvarchar](50) NULL,
[UpdDate] [datetime] NULL,
[UpdUser] [nvarchar](50) NULL,
CONSTRAINT [PK_EVKpiInfo] PRIMARY KEY CLUSTERED
(
[KpiNo] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] GO
/****** Object: Table [dbo].[kpi1447055501128] Script Date: 2016/3/25 16:06:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[kpi1447055501128](
[KpiNo] [nvarchar](50) NOT NULL,
[KpiName] [nvarchar](50) NULL,
[KpiInfo] [nvarchar](100) NULL,
[KpiParentNo] [nvarchar](50) NULL,
[KpiMethod] [nvarchar](50) NULL,
[KpiWeight] [decimal](18, 2) NULL,
[KpiRule] [nvarchar](100) NULL,
[KpiCriterion] [nvarchar](100) NULL,
[KpiAreaRule] [nvarchar](100) NULL,
[KpiSampleRule] [nvarchar](100) NULL,
[KpiAreaNum] [int] NOT NULL,
[KpiSampleNum] [int] NOT NULL,
[KpiMinValue] [decimal](18, 2) NULL,
[KpiMaxValue] [decimal](18, 2) NULL,
[KpiOffset] [decimal](18, 2) NULL,
[KpiReferenceVal] [decimal](18, 2) NULL,
[KpiValueType] [nvarchar](50) NULL,
[KpiFormula] [nvarchar](50) NULL,
[KpiFormulaRule] [nvarchar](100) NULL,
[KpiMemo] [nvarchar](100) NULL,
[KpiGoodMinValue] [decimal](18, 2) NULL,
[KpiGoodMaxValue] [decimal](18, 2) NULL,
[KpiGoodMethod] [nvarchar](50) NULL,
[KpiGoodOffset] [decimal](18, 2) NULL,
[KpiSampleType] [nvarchar](50) NULL
) ON [PRIMARY] GO
/****** Object: Table [dbo].[kpi20150002] Script Date: 2016/3/25 16:06:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[kpi20150002](
[KpiNo] [nvarchar](50) NOT NULL,
[KpiName] [nvarchar](50) NULL,
[KpiInfo] [nvarchar](100) NULL,
[KpiParentNo] [nvarchar](50) NULL,
[KpiMethod] [nvarchar](50) NULL,
[KpiWeight] [decimal](18, 2) NULL,
[KpiRule] [nvarchar](100) NULL,
[KpiCriterion] [nvarchar](100) NULL,
[KpiAreaRule] [nvarchar](100) NULL,
[KpiSampleRule] [nvarchar](100) NULL,
[KpiAreaNum] [int] NOT NULL,
[KpiSampleNum] [int] NOT NULL,
[KpiMinValue] [decimal](18, 2) NULL,
[KpiMaxValue] [decimal](18, 2) NULL,
[KpiOffset] [decimal](18, 2) NULL,
[KpiReferenceVal] [decimal](18, 2) NULL,
[KpiValueType] [nvarchar](50) NULL,
[KpiFormula] [nvarchar](50) NULL,
[KpiFormulaRule] [nvarchar](100) NULL,
[KpiMemo] [nvarchar](100) NULL,
[KpiGoodMinValue] [decimal](18, 2) NULL,
[KpiGoodMaxValue] [decimal](18, 2) NULL,
[KpiGoodMethod] [nvarchar](50) NULL,
[KpiGoodOffset] [decimal](18, 2) NULL,
[KpiSampleType] [nvarchar](50) NULL
) ON [PRIMARY] GO
/****** Object: Table [dbo].[KpiTree] Script Date: 2016/3/25 16:06:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[KpiTree](
[KpiNo] [nvarchar](50) NOT NULL,
[KpiName] [nvarchar](50) NULL,
[KpiInfo] [nvarchar](50) NULL,
[KpiParentNo] [nvarchar](50) NULL,
[KpiCollectMethod] [nvarchar](50) NULL,
[KpiWeight] [decimal](18, 2) NULL,
[KpiMemo] [nvarchar](100) NULL,
[KpiIndex] [int] NULL,
[IsDLT] [smallint] NULL,
[CrtDate] [datetime] NULL,
[CrtUser] [nvarchar](50) NULL,
[UpdDate] [datetime] NULL,
[UpdUser] [nvarchar](50) NULL,
CONSTRAINT [PK_KpiTree] PRIMARY KEY CLUSTERED
(
[KpiNo] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] GO
/****** Object: Table [dbo].[kpitree1447055501128] Script Date: 2016/3/25 16:06:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[kpitree1447055501128](
[KpiNo] [nvarchar](50) NOT NULL,
[KpiName] [nvarchar](50) NULL,
[KpiInfo] [nvarchar](50) NULL,
[KpiParentNo] [nvarchar](50) NULL,
[KpiCollectMethod] [nvarchar](50) NULL,
[KpiWeight] [decimal](18, 2) NULL,
[KpiMemo] [nvarchar](100) NULL,
[KpiIndex] [int] NULL
) ON [PRIMARY] GO
/****** Object: Table [dbo].[KpiTree20150002] Script Date: 2016/3/25 16:06:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[KpiTree20150002](
[KpiNo] [nvarchar](50) NOT NULL,
[KpiName] [nvarchar](50) NULL,
[KpiInfo] [nvarchar](50) NULL,
[KpiParentNo] [nvarchar](50) NULL,
[KpiCollectMethod] [nvarchar](50) NULL,
[KpiWeight] [decimal](18, 2) NULL,
[KpiMemo] [nvarchar](100) NULL,
[KpiIndex] [int] NULL
) ON [PRIMARY] GO
/****** Object: Table [dbo].[KpiValue] Script Date: 2016/3/25 16:06:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[KpiValue](
[TenderNo] [nvarchar](50) NOT NULL,
[KpiNo] [nvarchar](50) NOT NULL,
[KpiValue1] [decimal](18, 2) NULL,
[KpiValue2] [decimal](18, 2) NULL,
[SampleNumAll] [int] NULL,
[SampleNum1] [int] NULL,
[SampleNum2] [int] NULL
) ON [PRIMARY] GO
/****** Object: Table [dbo].[KpiValue1447055501128] Script Date: 2016/3/25 16:06:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[KpiValue1447055501128](
[TenderNo] [nvarchar](50) NOT NULL,
[KpiNo] [nvarchar](50) NOT NULL,
[KpiValue1] [decimal](18, 2) NULL,
[KpiValue2] [decimal](18, 2) NULL,
[SampleNumAll] [int] NULL,
[SampleNum1] [int] NULL,
[SampleNum2] [int] NULL
) ON [PRIMARY] GO
/****** Object: Table [dbo].[KpiValue20150002] Script Date: 2016/3/25 16:06:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[KpiValue20150002](
[TenderNo] [nvarchar](50) NOT NULL,
[KpiNo] [nvarchar](50) NOT NULL,
[KpiValue1] [decimal](18, 2) NULL,
[KpiValue2] [decimal](18, 2) NULL,
[SampleNumAll] [int] NULL,
[SampleNum1] [int] NULL,
[SampleNum2] [int] NULL
) ON [PRIMARY] GO
ALTER TABLE [dbo].[Kpi] ADD CONSTRAINT [DF_Kpi_KpiWeight] DEFAULT ((1)) FOR [KpiWeight]
GO
ALTER TABLE [dbo].[Kpi] ADD CONSTRAINT [DF_Kpi_KpiAreaNum] DEFAULT ((2)) FOR [KpiAreaNum]
GO
ALTER TABLE [dbo].[Kpi] ADD CONSTRAINT [DF_Kpi_KpiSampleNum] DEFAULT ((10)) FOR [KpiSampleNum]
GO
ALTER TABLE [dbo].[Kpi] ADD CONSTRAINT [DF_Kpi_IsDLT] DEFAULT ((0)) FOR [IsDLT]
GO
ALTER TABLE [dbo].[kpi20150002] ADD CONSTRAINT [DF_kpi20150002_KpiWeight] DEFAULT ((1)) FOR [KpiWeight]
GO
ALTER TABLE [dbo].[KpiTree] ADD CONSTRAINT [DF_KpiTree_KpiWeight] DEFAULT ((1)) FOR [KpiWeight]
GO
ALTER TABLE [dbo].[KpiTree] ADD CONSTRAINT [DF_KpiTree_IsDLT] DEFAULT ((0)) FOR [IsDLT]
GO
ALTER TABLE [dbo].[KpiTree20150002] ADD CONSTRAINT [DF_KpiTree20150002_KpiWeight] DEFAULT ((1)) FOR [KpiWeight]
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'指标编号' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Kpi', @level2type=N'COLUMN',@level2name=N'KpiNo'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'指标名称' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Kpi', @level2type=N'COLUMN',@level2name=N'KpiName'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'上级指标编号' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Kpi', @level2type=N'COLUMN',@level2name=N'KpiParentNo'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'权重' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Kpi', @level2type=N'COLUMN',@level2name=N'KpiWeight'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'上级指标编号' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Kpi', @level2type=N'COLUMN',@level2name=N'KpiRule'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'权重' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Kpi', @level2type=N'COLUMN',@level2name=N'KpiCriterion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'指标配置表' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Kpi'
GO

议:如何将树形菜单形式的数据转化成HTML的二维表(相同内容需合并单元格)的更多相关文章

  1. Aspose.Cells 首次使用,用到模版填充数据,合并单元格,换行

    Aspose.Cells 首次使用,用到模版填充数据,合并单元格,换行 模版格式,图格式是最简单的格式,但实际效果不是这种,实际效果图如图2 图2 ,注意看红色部分,一对一是正常的,但是有一对多的订单 ...

  2. layui:数据表格如何合并单元格

    layui.use('table', function () { var table = layui.table; table.render({ elem: '#applyTab' , url: '$ ...

  3. 雷林鹏分享:jQuery EasyUI 数据网格 - 合并单元格

    jQuery EasyUI 数据网格 - 合并单元格 数据网格(datagrid)经常需要合并一些单元格.本教程将向您展示如何在数据网格(datagrid)中合并单元格. 为了合并数据网格(datag ...

  4. js动态加载数据并合并单元格

    js动态加载数据合并单元格, 代码如下所示,可复制直接运行: <!DOCTYPE HTML> <html lang="en-US"> <head> ...

  5. .Net用字符串拼接实现表格数据相同时合并单元格

    前言 最近在做项目通过GridView或Repeater绑定数据,如果两行或若干行某列值相同,需要进行合并单元格,但是实现过程中想到了字符串拼接,于是就没用绑定数据控件,而是用了html结合字符串实现 ...

  6. [办公应用]如何将excel合并单元格分拆后每个单元格上仍保留数据?

    合并单元格虽然美观,但是无法进行排序.筛选等操作. 只有合并单元格拆分后才可以按常规进行统计.但是普通拆分后,excel仅保留合并单元格数据到区域左上角的单元格. 解决方案:选定多个合并单元格,应用本 ...

  7. php 数据导出到excel 2种带有合并单元格的导出

    具体业务层面 可能会有所不同.以下两种方式涉及的合并单元格地方有所不同,不过基本思路是一致的. 第一种是非插件版本.可能更容易理解点,基本思路就是 组装table 然后 读取 输出到excel上.缺点 ...

  8. 数据可视化之PowerQuery篇(四)二维表转一维表,看这篇文章就够了

    https://zhuanlan.zhihu.com/p/69187094 数据分析的源数据应该是规范的,而规范的其中一个标准就是数据源应该是一维表,它会让之后的数据分析工作变得简单高效. 在之前的文 ...

  9. 【Excle数据透视表】如何在数据透视表中使用合并单元格标志

    先有数据透视表如下: 现在看着这个格式不舒服,我们希望调整成如下这种样式 步骤 单击数据透视表任意单元格→右键→数据透视表选项→布局和格式→合并且居中排列带标签的单元格 注意:如果数据透视表报表布局不 ...

随机推荐

  1. HW5.33

    import java.util.Calendar; public class Solution { public static void main(String[] args) { long tot ...

  2. openstack rc

    #!/bin/bash export OS_PROJECT_DOMAIN_ID=default export OS_USER_DOMAIN_ID=default export OS_PROJECT_N ...

  3. phonegap Overview

    PhoneGap 和 Cordova的关系阐述 是PhoneGap贡献给Apache后的开源项目,是从PhoneGap中抽出的核心代码,是驱动PhoneGap的核心引擎.你可以把他想象成类似于Webk ...

  4. (step 4.3.5)hdu 1035(Robot Motion——DFS)

    题目大意:输入三个整数n,m,k,分别表示在接下来有一个n行m列的地图.一个机器人从第一行的第k列进入.问机器人经过多少步才能出来.如果出现了循环 则输出循环的步数 解题思路:DFS 代码如下(有详细 ...

  5. Struts—自定义一个简单的mystruct

    传统mvc开发总结: 1. 跳转代码写死,不灵活 2. 每次都去写servlet,web.xml中配置servlet! (配置目的: 请求, Servlet处理类) 一个简单的struct案例,描述如 ...

  6. iOS开发- 文件共享(利用iTunes导入文件, 并且显示已有文件)

    实现过程: 1.在应用程序的Info.plist文件中添加Application supports iTunes file sharing键,并将键值设置为YES. - (void)viewDidLo ...

  7. [Java][Android][Process] 暴力的服务能够解决一切,暴力的方式运行命令行语句

    不管是在Java或者Android中运行命令行语句殊途同归都是创建一个子进程运行调用可运行文件运行命令.类似于Windows中的CMD一样. 此时你有两种方式运行:ProcessBuilder与Run ...

  8. 【36】绝不重新定义继承而来的non-virtual方法

    1.绝不重新定义继承而来的non-virtual方法,为什么? 首先想想,non-virtual方法是干什么的?也就是说,它的使用场景.父类的non-virtual方法,其实就是告诉子类,继承实现,子 ...

  9. Nginx开发从入门到精通

    nginx由于出色的性能,在世界范围内受到了越来越多人的关注,在淘宝内部它更是被广泛的使用,众多的开发以及运维同学都迫切的想要了解nginx模块 的开发以及它的内部原理,但是国内却没有一本关于这方面的 ...

  10. C++在使用Qt中SLOT宏须要注意的一个小细节

    大家都知道C++虚函数的机制,对于基类定义为虚函数的地方,子类假设覆写,在基类指针或者引用来指向子类的时候会实现动态绑定. 但假设指针去调用非虚函数,这个时候会调用C++的静态绑定,去推断当前的指针是 ...