浅谈Excel导入和后台处理

1. 导入方法

procedure TfrmSalarySmallPartsRecords.btnExcelToSQLClick(Sender: TObject);
var
  cntI: Integer;
  sTmptbname,sFileName, sSQL,checkSql: string;
  ExcelID, Sheet, errsheet: Variant;
  FFieldString: string;
  i, j, FCount, ExcelRowCount, errint: integer;
  errbl: boolean;
  vworkerID,vworkerName,vsortType,veffectiveDate:String;  qryTemp2:TADOQuery;
begin
  inherited;
  sTmptbname:=‘##tmptb‘+formatdatetime(‘yyyymmddhhMMsszzzz‘,now);
  with open1 do
  begin
    if Execute then
      sFileName := FileName
    else
      exit;
  end;
  
  with qryInput do
  begin
    Close;
    SQL.Clear;
    SQL.Add(‘select * into ‘+sTmptbname+‘ from TargetTable(nolock) where 1<>1‘);
    execsql;

    close;
    sql.Text:=‘select * from ‘+sTmptbname+‘‘;
    open;
  end;

  try
    ExcelID := CreateOleObject(‘Excel.Application‘);
    ExcelID.Visible := False;
  except
    on E: Exception do
    begin
      ExcelID.Quit;
      ExcelID := Unassigned;
      MessageBox(Self.Handle, Pchar(‘创建Excel对象出错,原因为:‘ + e.Message), Pchar(AppliCation.Title), MB_OK + MB_ICONERROR);
      Exit;
    end;
  end;

  FFieldString := ‘workerName;workerID;effectiveDate;styleno;remark;qty;sortType;sortName;bgprice‘;
  FCount := CountChar(‘;‘, FFieldString);
  errbl:=false;
  try
    try
      ExcelID.WorkBooks.Open(sFileName);
      Sheet := ExcelID.WorkBooks[1].WorkSheets[1];
      errsheet := ExcelID.WorkBooks[1].WorkSheets[2];
      ExcelRowCount := ExcelID.WorkSheets[1].UsedRange.Rows.Count; //获得本数据表有多少行数据
      errint := 1;                             //开始事务

      for i := 2 to ExcelRowCount do                                //将要从哪行开始读
      begin
        if length(trim(Sheet.Cells[i, 2].Value)) <= 0 then
          break;   //如果第二个单元格(工号)为空,则提前结束循环,此处也可以用其它方式结束

        with qryInput do
        begin
          Append;
          FieldByName(‘inDate‘).Value := GetNowTime;

          for j := 0 to FCount do
          begin
            if (j = 0) or (j = 7) then     //姓名、配件名称
            begin
              vworkerName:= Sheet.Cells[i,j+1].Value ;
              Continue;
            end
            else
            if j = 1 then     //工号
            begin
              //  判断工号是否存在      vworkerID
              vworkerID := Sheet.Cells[i,j+1].Value ;
              with qrytemp do
              begin
                Close;
                SQL.text:=‘select top 1 empid,empname from Employees where empid = ‘ + QuotedStr(vworkerID) ;
                Open;
              end;
              if qrytemp.IsEmpty then
              begin
                  errsheet.Cells[errint,1]:=‘行‘+inttostr(i)+‘ ‘+vartostr(Sheet.Cells[i,j+1])+‘ 找不到对应的工号!‘;
                  inc(errint);
                  errbl:=true;
              end
              else
              begin
                if vworkerName<>qrytemp.FieldByName(‘empname‘).AsString then
                begin
                  errsheet.Cells[errint,1]:=‘行‘+inttostr(i)+‘ ‘+vartostr(Sheet.Cells[i,j+1])+‘ 工号与姓名不符合!‘;
                  inc(errint);
                  errbl:=true;
                  FieldByName(‘workerID‘).AsString:= vworkerID;
                  FieldByName(‘workerName‘).AsString:= qrytemp.FieldByName(‘empname‘).AsString;
                end
                else
                begin
                  FieldByName(‘workerID‘).AsString:= vworkerID;
                  FieldByName(‘workerName‘).AsString:= qrytemp.FieldByName(‘empname‘).AsString;
                end;
              end;
            end
            else if j = 2 then   //作业日期  veffectiveDate
            begin
              veffectiveDate:= Sheet.Cells[i,j+1].Value;
              if (veffectiveDate = ‘‘) OR (veffectiveDate = ‘1899-12-30‘) OR (veffectiveDate = ‘1900-01-01‘) OR (veffectiveDate = ‘1999-12-30‘) then
              begin
                FieldByName(CopySubStr(FFieldString,j)).Value := null;
                errsheet.Cells[errint,1]:=‘行‘+inttostr(i)+‘ ‘+vartostr(Sheet.Cells[i,j+1])+‘ 作业日期不能为空!‘;
                inc(errint);
                errbl:=true;
                FieldByName(CopySubStr(FFieldString,j)).Value := veffectiveDate;
              end
              else
              begin
                FieldByName(CopySubStr(FFieldString,j)).Value := veffectiveDate;
              end;
            end
            else if j = 5 then   //件数/工时
            begin
              if (Sheet.Cells[i,j+1].Value<=0) or (Sheet.Cells[i,j+1].Value>99999) then
              begin
                errsheet.Cells[errint,1]:=‘行‘+inttostr(i)+‘ ‘+vartostr(Sheet.Cells[i,j+1])+‘ 件数/工时错误!‘;
                inc(errint);
                errbl:=true;
                FieldByName(CopySubStr(FFieldString,j)).Value := Sheet.Cells[i,j+1].Value;
              end
              else
              begin
                FieldByName(CopySubStr(FFieldString,j)).Value := Sheet.Cells[i,j+1].Value;
              end;
            end
            else if j = 6 then   //配件类型    vsortType
            begin
              vsortType := Sheet.Cells[i,j+1].Value ;
              with qrytemp do
              begin
                Close;
                SQL.text:=‘select top 1 sortType,sortDesc from tab_smallPartsSort where sortType = ‘ + QuotedStr(vsortType) ;
                Open;
              end;
              if qrytemp.IsEmpty then
              begin
                  errsheet.Cells[errint,1]:=‘行‘+inttostr(i)+‘ ‘+vartostr(Sheet.Cells[i,j+1])+‘ 找不到对应的配件类型!‘;
                  inc(errint);
                  errbl:=true;
              end
              else
              begin
                FieldByName(‘sortType‘).AsString:= vsortType;
                FieldByName(‘sortName‘).AsString:= qrytemp.FieldByName(‘sortDesc‘).AsString;
                //TT001,TT002:计时类型
                if (vsortType=‘TT001‘) or (vsortType=‘TT002‘) then
                   FieldByName(‘priceType‘).AsString:= ‘T‘
                else
                   FieldByName(‘priceType‘).AsString:= ‘P‘;
              end;
            end
            else
            begin
              FieldByName(CopySubStr(FFieldString, j)).Value := Sheet.Cells[i, j + 1].Value;
            end;
          end;

          if  not errbl then
            post;

        end;
      end;

      {判断插入的记录是否有重复_begin}
      checkSql:=‘SELECT workerid,pricetype,effectivedate,sorttype,styleno,COUNT(*) cc FROM  ‘ + sTmptbname
              + ‘ GROUP BY workerid,pricetype,effectivedate,sorttype,styleno ‘
              + ‘ HAVING COUNT(*) >1‘;   try      qryTemp2:=TADOQuery.Create;      qryTemp2.connection:=DbFrm.cn;
      with qrytemp2 do
      begin
        Close;
        SQL.Clear;
        sql.Add(checkSql);
        Open;
      end;
      if qrytemp2.RecordCount>0 then  //有重复记录
      begin
          MessageDlg(‘导入数据出错,款号记录‘+qrytemp2.fieldbyname(‘styleno‘).AsString+‘有重复!‘,mtWarning,[mbOK],0);
          with qryInput do
          begin
            Close;
            SQL.Clear;
            SQL.Add(‘drop table  ‘+sTmptbname);
            execsql;
          end;
          exit;
      end;
      {判断插入的记录是否有重复_end}
   finnaly     qryTemp2.Free;   end;

      if  errbl then
      begin
        ExcelID.DisplayAlerts:=false;
        messagedlg(‘导入数据出错,请看文件第二页,查看详细原因!‘,mtwarning,[mbok],0);

        ExcelID.save;

        with qryInput do
        begin
          Close;
          SQL.Clear;
          SQL.Add(‘drop table  ‘+sTmptbname);
          execsql;
        end;
        exit;
      end;
      //ShowMesStr(‘导入数据成功完成!‘, ‘010‘);
    except
      on E: Exception do
      begin
        MessageBox(Self.Handle, Pchar(‘系统提示您,数据导入失败,原因为:‘ + e.Message), Pchar(AppliCation.Title), MB_OK + MB_ICONERROR);
         with qryInput do
         begin
           Close;
           SQL.Clear;
           SQL.Add(‘drop table  ‘+sTmptbname);
           execsql;
         end;
         exit;
      end;
    end
  finally
    ExcelID.WorkBooks[1].Close(false, ‘‘);
    ExcelID.Quit;
    ExcelID := Unassigned;
    sheet := Unassigned;
  end;
  //利用服务器存储过程处理导入数据
  sSQL:= ‘exec UpDemo :tmptb‘;
  sSQL:=StringReplace(sSQL,‘:tmptb‘,sTmptbname,[rfIgnoreCase,rfReplaceAll]);
  with qrytemp do
  begin
    Close;
    SQL.Clear;
    SQL.Add(ssql);
    ExecSQL;
  end;

  ShowMesStr(‘导入更新数据成功完成,请重新查询!‘,‘010‘);
end;

2. 后台处理的存储过程(UpDemo):如果数据存在且未审核就修改相关信息;如果不存在,则插入数据

CREATE PROCEDURE UpDemo
 @tmptbname varchar(30)
AS
BEGIN
 declare @sql varchar(4000),
  @sql2 VARCHAR(1000)                                

 SET @sql=‘
 MERGE TargetTable t
 USING (SELECT  b.workerID,a.workerName,a.priceType,a.effectiveDate,a.sortType,a.sortName,a.styleno,a.bgprice
  ,a.inDate,a.inUserID,a.inUserDate,a.qty,a.checkUserID,a.checkDate,a.isConfirm,a.remark
        from ‘+ @tmptbname +‘ a LEFT JOIN
    (SELECT empid AS workerID,empname FROM Employees) b ON b.empname=a.workerName
  WHERE NOT EXISTS (SELECT t.workerID,t.priceType,t.sortType,t.effectiveDate
                           FROM TargetTable t WHERE t.workerID=a.workerID
                           AND t.priceType=a.priceType
                           AND t.sortType=a.sortType
                           AND t.effectiveDate=a.effectiveDate
                           AND t.styleno=a.styleno
                           AND t.isConfirm=1  )  --过滤审核过的数据不可修改
      ) s
 ON  t.workerID=s.workerID and t.priceType=s.priceType  AND t.styleno=s.styleno
 and t.sortType=s.sortType and t.effectiveDate=s.effectiveDate
 WHEN matched
 THEN UPDATE SET t.sortName=s.sortName,t.qty=s.qty,t.bgprice=s.bgprice,
                 t.inUserID=s.inUserID,t.InDate=s.InDate,t.inUserDate=s.inUserDate,t.Remark=s.Remark
 WHEN NOT MATCHED
 THEN INSERT (workerID,workerName,priceType,effectiveDate,sortType,sortName,styleno,bgprice,inDate,inUserID,inUserDate,qty,checkUserID,checkDate,isConfirm,remark)
   VALUES(workerID,workerName,priceType,effectiveDate,sortType,sortName,styleno,bgprice,inDate,inUserID,inUserDate,qty,checkUserID,checkDate,isConfirm,remark);
  ‘      

 SET @sql2=‘‘
 SET @sql2=@sql2+ ‘ drop table ‘+ @tmptbname            

 print @sql
 PRINT @sql2      

 exec (@sql+@sql2)          

END 
时间: 2024-08-15 00:13:05

浅谈Excel导入和后台处理的相关文章

VSTO学习笔记(九)浅谈Excel内容比较

原文:VSTO学习笔记(九)浅谈Excel内容比较 说起文件内容比较,或许我们首先想到的是UltraCompare这类专业比较的软件,其功能非常强大,能够对基于文本的文件内容作出快速.准确的比较,有详细的差异报告,非常便于分析.其实,各种版本控制软件中也包含有或多或少的比较功能,如TFS.CVS.SVN等.但是如果待比较的文件不是基于文本类型的,那就无能为力了.今天我就来谈一谈Excel的比较方法及其特点,也和大家共同探讨一下,如果你有更好的方法,欢迎分享. 一.Excel的文件架构 Excel

浅谈JNDI导入jar包的先后次序影响程序运行结果的问题

今天下午我做了一个关于学生信息管理系统的demo,主要功能是使用jdbc对学生信息进行增删改查,整体的逻辑按照JNDI进行,使用oracle数据库. 第一次运行,果不其然出现了异常,参照下图: 经过检查,我发现我oracle的jar包导入路径错了,没有按照JNDI中的要求导入到tomcat文件夹下的lib文件夹中,而是导入到了项目的lib文件夹中.我向tomcat文件夹下的lib文件夹中添加了同名的jar包,我以为这样一来,程序就能正常运行了. 然而并没有. 异常还是这个异常,ClassNotF

PL/SQL数据导入导出浅谈(1)

近来需要通过PL/SQL向Oracle中导数据,特此总结一下 试例表:test 字段:id;name;org; 1.直接复制粘贴(当数据量不是特别大的时候) 1)使用select * from test for update语句 2)执行之后,点击查询结果窗口左上方的小锁,打开之后,便可在相应的字段下面进行复制粘贴 3)粘贴结束之后,点击对号.之后提交事务即可. 优点:方便 缺点:当数据量比较大的时候准确度容易出差错 2.使用PL/SQL自带工具 1)准备数据,把需要导入的Excel文件另存为t

浅谈webform开发时前台请求后台数据的方法

说到前台请求后台数据,我们一般都是用到AJAX(异步JavaScript和XML) .AJAX 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着可以在不重新加载整个网页的情况下,我们可以对网页的某部分进行更新.在这里,主要浅谈一下在.net的webform开发时,前台请求后台的两种方式. 1.使用AjaxPro2.dll  (1)AjaxPro2.dll文件可以去网上下载,下载后引用到项目中. (2)引用到项目之后,在web.config里面的<system.web

浅谈控件(组件)制作方法一(附带一delphi导出数据到Excel的组件实例)(原创)

来自:http://blog.csdn.net/zhdwjie/article/details/1490741 ------------------------------------------------------------------- 从99年学习delphi开始,我就被它的快速开发迷上了,那时候刚接触编程,对可视化开发特别来劲,原因嘛,不外乎是比C更快的实现啦,这几年来,从delphi的C/S到三层B/S,大大小小也写过一些软件,自认为这delphi也就这么些功能吧,自从最近偶得一

浅谈 Python 的模块导入

浅谈 Python 的模块导入 本文不讨论 Python 的导入机制(底层实现细节),仅讨论模块与包,以及导入语句相关的概念.通常,导入模块都是使用如下语句: import ... import ... as ... from ... import ... from ... import ... as ... 一般情况下,使用以上语句导入模块已经够用的.但是在一些特殊场景中,可能还需要其他的导入方式.例如 Python 还提供了 __import__ 内建函数和 importlib 模块来实现动

笔记:浅谈 ETL(SSIS) 对 EXCEL源的处理

最近工作中刚好碰到excel 作为源导入db的需求,于是写下来帮助自己以后回顾和总结 逐步扩展对excel的处理 1.单纯的excel导入目标库 这步实现是最为简单,不考虑任何的扩展性和容错处理,缺点也很明显,源文件名和文件所在的路径都需要固定并且无法处理一个批次多个文件的情况 2.扩展循环处理多个文件 这种实现在上一种基础上添加了一层循环,对同一个folder下符合条件的文件进行循环导入,并做相应的文件处理操作. 1.首先建立个文件夹结构 files用来存放需要导入的excel文件,archi

浅谈HTTP响应拆分攻击

在本文中,我们将探讨何谓HTTP响应拆分以及攻击行为是怎样进行的.一旦彻底理解了其发生原理(该原理往往被人所误解),我们就可以探究如何利用响应拆分执行跨站点脚本(简称XSS).接下来自然就是讨论如果目标网站存在响应拆分漏洞,我们要如何利用这一机会组织CSRF(即跨站点伪造请求)攻击.最后,我们一起来看看哪些预防措施能够抵御这些攻击行为.如果大家对这个话题感兴趣,不妨继续读下去. 什么是HTTP响应拆分? 首先让我们设想一下某个具备多种语言选项的页面.该页面的默认语言为英语,但其中同时具备一个下拉

浅谈php生成静态页面

一.引 言 在速度上,静态页面要比动态页面的比方php快很多,这是毫无疑问的,但是由于静态页面的灵活性较差,如果不借助数据库或其他的设备保存相关信息的话,整体的管理上比较繁琐,比方修改编辑.比方阅读权限限制等,但是,对应一些我们经常频频使用的文件,比方说,开发的新闻发布系统,我们不希望很多用户都读取数据库才显示结果,这样一方面消耗了服务器的资源,另一方面占去了浏览者大量可贵的响应时间,所有,有了"静态页面话"的做法,当前很多网站都采用这种技术,一般都是由管理后台控制,或者生成html直