12。从excel导入:.
以前遇到过:处理方法:
#region 从Excel导入数据
public DataTable getDataFromExcel(string fileName, string sheetName)
{
string myConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + ";Extended Properties=\"Excel
8.0;HDR=Yes;IMEX=1\"";
//*.xsl可以认为是数据库了,HDR表示是否隐藏excel的第一行(因为第一行一般表示字段名称)
//IMEX 参数,因为不同的模式代表著不同的读写行为:当IMEX=0 时为“汇出模式”,这个模式开启的 Excel 档案只能用来做“写入
”用途。当 IMEX=1 时为“汇入模式”,这个模式开启的 Excel 档案只能用来做“读取”用途。当 IMEX=2 时为“连結模式”,这个模式开启
的 Excel 档案可同时支援“读取”与“写入”用途。
System.Data.OleDb.OleDbConnection myConnection = new System.Data.OleDb.OleDbConnection(myConn);
myConnection.Open();
string mySQLstr = "SELECT * FROM " + sheetName;
System.Data.OleDb.OleDbDataAdapter myDataAdapter = new System.Data.OleDb.OleDbDataAdapter(mySQLstr, myConnection);
DataSet myDS = new DataSet();
myDataAdapter.Fill(myDS); //把相关信息记录到DataSet中
myConnection.Close();
if (myDS != null && myDS.Tables.Count > 0)
{
return myDS.Tables[0];
}
return null;
}
#endregion
#region 导入项目信息
public void ImportProjectInfo(DataTable dt)
{
if (dt == null)
{
return;
}
int rowsCount = dt.Rows.Count;
int successedCount = 0;
int failedCount = 0;
bool isSuccessed = false;
for (int rowIndex = 0; rowIndex < rowsCount; rowIndex++)
{
try
{
para.ProjectNO = dt.Rows[rowIndex]["项目编号"].ToString();
para.ProjectName = dt.Rows[rowIndex]["项目名称"].ToString();
para.ProjectManager = dt.Rows[rowIndex]["项目组长"].ToString();
para.Language = dt.Rows[rowIndex]["开发语言"].ToString();
para.State = dt.Rows[rowIndex]["状态"].ToString();
para.EndTime = DateTime.Parse(dt.Rows[rowIndex]["结束时间"].ToString());
para.DevelopAddress = dt.Rows[rowIndex]["开发地点"].ToString();
para.Descript = dt.Rows[rowIndex]["项目描述"].ToString();
para.CertainTime = DateTime.Parse(dt.Rows[rowIndex]["开始时间"].ToString());
para.IdentifyCode = dt.Rows[rowIndex]["验证码"].ToString();
isSuccessed = FacadeProject.InsertProjectInfo(para);
}
catch (Exception ex)
{
//LogUtil.LogError("导入项目信息出错", ex);
//isSuccessed = false;
}
if (isSuccessed ==true )
{
successedCount++;
}
else
{
failedCount++;
}
}
if (successedCount > 0)
{
ShowMessage("成功导入" + successedCount + "条项目数据," + failedCount + "条失败");
}
LogUtil.Log("成功导入" + successedCount + "条公司信息," + failedCount + "条失败");
this.gvImportData.DataSource = dt;
this.gvImportData.DataBind();
}
#endregion
有几点:
1。应该使用事务导入,(在parameter中添加一个datatable,把从excel读的datatable赋给parameter,把插入的for循环也放在facade中)
2.实际中提供的模板可能有不规则的头部.(即第一行不一定就是表头)..可用datareader 一行一行读取.
3。下面用到的:没用datatable,直接在数据库建立临时表,把数据先插入临时表中,最后在导入,导入成功后删除临时表
这次采用方法主要语句:
//定义Excel连接
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + importFullName +
"';Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'" + ";");
OleDbCommand cmd = null;
OleDbDataReader rdr = null;
//定义Sql连接
SqlCommand comm = null;
SqlConnection myCon = null;
try
{
//打开Excel连接
conn.Open();
cmd = conn.CreateCommand();
//打开Sql连接
myCon = DBMgr.GetConnection();
myCon.Open();
//定义连接变量
string strSql = "";
comm = new SqlCommand(strSql, myCon);
#region 获取并校验Sheet的名字
//获取并校验Sheet的名字
DataTable dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
//定义两个变量获取Sheet的名字
string sheet1Name = "";
string sheet2Name = "";
//如果没有sheet
if (dt.Rows.Count == 0)
{
existError = true;
//添加错误日志消息
errorLogMessage.Add("导入失败,原因:文件没有sheet.");
//请确认至少有一个sheet且名称为'费率表数据'
ShowMessage(Consts.Messages.M_ImportQuotation_001);
return;
}
else{
sheet1Name = dt.Rows[1][2].ToString().Trim();
if (sheet1Name != "费率表数据$" )
{
ShowMessage(Consts.Messages.M_ImportQuotation_003);
return;
}
#region 将Sheet1数据导入费率表临时表
//创建费率表临时表
strSql = @"CREATE TABLE #OCS_TT_RateCategory
(RateCategory_ID int,
Service_ID nvarchar(10),
DestZone_ID int,
DispOrder int,
CWBType nvarchar(3))";
comm.CommandText = strSql;
comm.ExecuteNonQuery();
//读取第一个Sheet
cmd.CommandText = "SELECT * FROM [费率表数据$]";
rdr = cmd.ExecuteReader();
rdr.Read(); //标题行
rdr.Read();
rdr.Read();
while (rdr.Read())
{
//读到空行则跳出循环
if (rdr.GetValue(0).ToString() == "" & rdr.GetValue(1).ToString() == "" & rdr.GetValue(2).ToString() == ""
& rdr.GetValue(3).ToString() == "" & rdr.GetValue(4).ToString() == "" & rdr.GetValue(5).ToString() == "" & rdr.GetValue
(6).ToString() == "")
{
break;
}
//接受数据集中的数据
if (rdr.GetValue(0).ToString() != "")
{
intRateCategoryID = Convert.ToInt32(rdr.GetValue(0));
//if (intRateCategoryID == intPreRateCategoryID)
//{
// existError = true;
// ShowMessage("费率表数据中的费率表编号有重复!");
// return;
//}
}
esle{
//-------
}
//当成功后在从临时表,插入到实际表操作略
}
}
13..现在有的一期代码(项目):report报表,web,webService.
其中web -->架构::: 采用的UI(css,js,image, 其他功能块)- parameter-Facade(包含通用util文件夹) - dal(包含
dao,data,webreferences,smartgridview)-公司内部通用dal ====架构.
-->ui 用的是iframe
-->功能包含::标准报价规则[始发区,目的区,始发地/目的地分区,服务类别,标准报价,标准报价记录导入导出,以及导出(DOC,SPS的标
准和明细格式报价报表)]
--折扣计算规则[折扣模板|设置客户折扣模板|导出折扣计算规则记录|导入折扣计算规则记录]
--附加费计算规则[附加费模板|附加费规则|附加费模板与附加费规则关系|设置客户附加费模板] 其中(导出(DOC,SPS的
标准和明细格式报价报表)采用的跳转到类似http://192.168.100.136/ReportServer/Pages/ReportViewer.aspx?%2fOCS_MSCRM%2f%e6%a0%87%
e5%87%86%e8%b4%b9%e7%8e%87%e8%a1%a8(DOC)&rs:Command=Render" 的网页,其他使用的是本项目内的页面
14。.今天主要分析下:报表[主要是数据库部分]----找不到对应数据库(或者表描述) -先看代码,找出疑问点和特别的
(1)sql相关:
sSql = "SELECT dbo.FCH_SubCompany.fch_companycode_nv "
+"FROM dbo.FCH_SubCompany, dbo.SystemUser"
+" Where dbo.FCH_SubCompany.fch_subcompanyid = dbo.SystemUser.fch_subcompany_lv "
+"AND dbo.SystemUser.systemuserid = '"+ id +"'";
与 string sSql = " SELECT a.fch_companycode_nv "+
" FROM fch_subcompany AS a INNER JOIN systemuser AS b ON a.fch_SubcompanyId = b.fch_subcompany_lv "+
" WHERE b.SystemUserID = '" + userId + "'";
即从两表选时,用inner join 和不用 ,有何差别?
(2) //定义一个StringBuilder类型用于多条件查询的实现
StringBuilder strCmd = new StringBuilder(@"SELECT Key_Description,
Key_Value
FROM dbo.OCS_MS_SystemConst
WHERE Key_Name = 'IsPromotion' ");
有一张字典常量表---OCS_MS_SystemConst(name,value,description);
(3) //定义一个StringBuilder类型用于多条件查询的实现
StringBuilder strCmd = new StringBuilder(@"SELECT adc.DsctCategory_ID,
dc.DsctCategory_Name,
adc.ValidFrom,
adc.ValidTo,
adc.AcctDsctCategory_ID,
sc.Key_Description AS IsPromotion,
sy.Key_Description as DsctPayType,
sys.Key_Description as Is_Disabled,
dc.Remarks,
dc.OrigZone_ID,
dc.BranchCom_ID
FROM dbo.OCS_MS_DsctCategory dc ,
dbo.OCS_MS_SystemConst sc,
dbo.OCS_MS_SystemConst sy,
dbo.OCS_MS_SystemConst sys,
dbo.OCS_TB_AcctDsctCategory adc
WHERE adc.DsctCategory_ID = dc.DsctCategory_ID
AND adc.AcctID = @AcctID
AND sc.Key_Value = @IsPromotion
AND sc.Key_Name = 'IsPromotion'
AND sy.Key_Value = @DsctPayType
AND sy.Key_Name = 'DsctPayType'
AND sys.Key_Value = adc.Is_Disabled
AND sys.Key_Name = 'Is_Disabled'
AND sc.Key_Value = dc.IsPromotion
AND sy.Key_Value = dc.DsctPayType");
当很多张表时,不用inner join ,直接from 各个表,用where tb1.id3 = tb2.id3 .并为关联字段起一个别名如: sc.Key_Description AS
IsPromotion,
(4) if (strDsctCategoryName != null)
{
//加入OWNERCODE条件
strCmd.Append(" AND dc.DsctCategory_Name like @DsctCategory_Name ");
cmd.Parameters.Add(new SqlParameter("@DsctCategory_Name", SqlDbType.NVarChar));
cmd.Parameters["@DsctCategory_Name"].Value = '%' + strDsctCategoryName + '%';
}
当查询条件不固定时,可以用StringBuilder strCmd,然后strCmd.Append(" AND dc.DsctCategory_Name like @DsctCategory_Name ");添加更
多的查询条件
------用此替代,曾见过的string str , str+=" ---" //防注入?
(5) //定义一个StringBuilder类型用于多条件查询的实现
StringBuilder strCmd = new StringBuilder(@"select count(*) from
OCS_TB_AcctDsctCategory t inner join
OCS_MS_DsctCategory m
on t.DsctCategory_ID = m.DsctCategory_ID
where m.OrigZone_ID=@OrigZone_ID and
m.IsPromotion =@IsPromotion and
m.DsctPayType=@DsctPayType and
t.AcctID = @AcctID and
t.is_disabled = 0 and
not (
t.ValidFrom > @ValidTo or
t.ValidTo < @ValidFrom
) ");
利用not,,表中一个开始时间,一个截止时间,,查看是新数据 对应的开始截止时间 是否有交叉. where 先查没有交叉的(当 开始时间< 截止时
间 或者截止时间大于开始时间 一条满足即有交叉) 然后加 not kao ,,牛逼!
(6)一些默认的:表有通用字段,isdisable (是否启用),createBy,createOn,updateBy,updateOn ,当添加时createOn 在dao赋值当前时间,更新时
updateOn赋值当前时间,不需要 页面传对应值..对于启用,不启用的,也写俩个方法,在dao处理,而不是在调用时赋值是否启用
:开始时间要小于结束时间
(7)/// 取得用户网络身份验证
using System.Net;
private NetworkCredential getDemo(string name,string password,string demo)
{
//NetworkCredential credentials = new NetworkCredential("crmadmin", "Pa$$w0rd", "CRMDEMO");
NetworkCredential credentials = new NetworkCredential(name, password, demo);
return credentials;
}
也不知道啥用,,曾写邮件发送时遇到过
(8) 类似这种public DataTable QueryIsDeleted(int? origZone_ID) ?啥意思??
(9) AND DsctRule_ID IN (SELECT DsctRule_ID
FROM dbo.OCS_MS_DsctRule
WHERE DsctCategory_ID = @dsctCategory_ID
AND Is_Deleted='0')
AND DsctRuleDetail_ID IN (SELECT DsctRuleDetail_ID
FROM dbo.OCS_MS_DsctRuleDetail
WHERE DsctCategory_ID = @dsctCategory_ID
AND Is_Deleted='0')
查询语句,包含的
(10)[1] SELECT case when tt.id = '1' then '男' else '女' end [sex]
,[name]
,[startTime]
,[endTime]
FROM [sss].[dbo].[tbTest] tt
存储过程时:语句 case when ** then ** else ** end 的使用
(11)SELECT case when tt.id <>isnull(tt.name,'') then '男' else '女' end [sex] ,isnull(tt.name,'') FROM [sss].[dbo].
[tbTest] tt
存储过程时:语句 isnull(field,string) 返回的是field的值,
(12) 如:CREATE TABLE #tmp(
[RowId] [int] identity(1,1) ,
[schgName] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL)
写存储过程常创建临时表,表名字前加#号,刷新表不会看到,是临时的. 删除记录delete from #tmp --- ,删除表drop table #tmp
(13) CREATE procedure [dbo].[Pr_Calc_OverseaCostByCWBNo]
(@cwb_no varchar(20)
,@LocalCost money output)
AS
BEGIN
SET NOCOUNT ON
***************
SET NOCOUNT OFF
END
初次建时create ,再次建时alert ,传出参数用output .SET NOCOUNT ON 指不返回sql操作影响的行数..
(14)----------汇总总金额------------------------------------------------------------
select @cur=a.CUR,
@ForeignCost=a.cost1,
@LocalCost=a.cost2
from(
select cur, sum(Cost) cost1,sum(Cost*ExgRate.ExchangeRate) cost2
from #tmp inner join BL_MS_ExchangeRate ExgRate
on ExgRate.AccPeriod=#tmp.AccPeriod and ExgRate.CurrencyCategory=#tmp.CUR
group by #tmp.CUR
) a
存储过程中,常出现,不断的嵌套,再嵌套,要写清排版,别乱了,,,另外sum(money) group by month 按月计算money
15。看以前的设计文档 --一看业务就头晕,服了
(1)维护路区预算导入 .. 开发路区预算导入.
折扣规则设定::