var    xlsFilename: string;
    MyWorkBook,ExcelApp: OleVariant;
    J,i : integer;begin       ExcelApp:=CreateOLEObject('Excel.Application');
       MyWorkBook:=ExcelApp.WorkBooks.Open(xlsFilename);
       J:=MyWorkBook.ActiveSheet.UsedRange.Rows.Count;       try
        i:=1;
        while i<j+1 do
         begin
          ADOQuery1.ConnectionString:=connetstr;
          ADOQuery1.SQL.Clear;
          ADOQuery1.SQL.Add('insert into B(BID,Bcaption,DFF,TF)');
          ADOQuery1.SQL.Add('values('''+uppercase(Trim(MyWorkBook.WorkSheets[1].Cells[i,1]))+''','''+uppercase(Trim(MyWorkBook.WorkSheets[1].Cells[i,2]))+''','''+uppercase(Trim(MyWorkBook.WorkSheets[1].Cells[i,5]))+''',cast('''+uppercase(Trim(MyWorkBook.WorkSheets[1].Cells[i,6]))+''' as int))');
          ADOQuery1.ExecSQL; 
i:=i+1;                                                                                  
         end;
       except
         ShowMessage('Excel文件格式不对或存在其他问题!请修正后再进行导入.');
         Exit;
       end;
end;
其中BID是主关键字,不能为空!在执行数据导入时出现“不能插入重复值”的提示,但是我的Excel表没有重复值,检查数据表B后,
发现有一条记录是空的,而Excel表的数据却已经导入到SQL数据库的表B里啦。如果把BID不设置为主关键字,也不能为空,数据是可以导入到数据库里,但是出现很多空的记录!请问我的导入操作有什么问题?谢谢!

解决方案 »

  1.   

    我本人认为是
     J:=MyWorkBook.ActiveSheet.UsedRange.Rows.Count;
    的问题!它是检索Excel工作表所有的行数,而不是检索有内容的行数!不知道要怎么去检索有内容的行数!
      

  2.   

    应该就是楼上说的问题,“检索Excel工作表所有的行数,而不是检索有内容的行数!”插入数据前做个判断吧,看看单元格内容是否为空。
      

  3.   

    怎么检索Excel工作表不为空的格子啊?希望知道的不吝赐教!谢谢!
      

  4.   

    先导到DataSet如:
    string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+Page.MapPath("TempFile\\"+Session["TempFileName"].ToString())+";Extended Properties=Excel 8.0;";
    OleDbConnection Oleconn = new OleDbConnection(strConn);
    OleDbDataAdapter adp = new OleDbDataAdapter("SELECT * FROM [Sheet1$]",strConn);
    DataSet ds = new DataSet();
    try
    {
    adp.Fill(ds);
    Datagrid1.DataSource = ds.Tables[0].DefaultView;
    Datagrid1.DataBind();
    }
    catch(Exception ex)
    {
    if(ex.ToString().IndexOf("不是预期的格式")>0)
    lbl_errors.Text="上传的Excel表格不是真正的Excel格式,请建立正确的Excel格式成绩表后再上传.";
    else
    lbl_errors.Text="上传错误,"+ex.ToString();
    //删除上传的Excel文件
    File.Delete(Page.MapPath("TempFile\\"+Session["TempFileName"].ToString()));
    return;
    }再循环判断 如:
    for(i=0;i<ds.Tables[0].Rows.Count;i++)
    {
    dr=ds.Tables[0].Rows[i];
    //Response.Write(dr[0].ToString()+"   "+dr[1].ToString()+"<br>");
    //这里写判断条件
    if(dr[0].ToString().Trim()=="")
    {
        //是空则不插入
    }
    else
    {
       strSQL="insert into 表名(字段名,字段名...)valuse(dr[0].ToString(),dr[1].ToString(),....);
       //写入表
       //自己写吧,这就不用我教了吧
    }
    }
      

  5.   

    发错代码了,还以为这是C#版块呢,不过delphi的实现也可以使用我的这个方法
      

  6.   

    我觉得只要是空就不插入数据库就可以了
    ...
    ADOQuery1.SQL.Clear;
    if Trim(MyWorkBook.WorkSheets[1].Cells[i,1])<>'' then do
    begin
    ADOQuery1.SQL.Add('insert into B(BID,Bcaption,DFF,TF)');
              ADOQuery1.SQL.Add('values('''+uppercase(Trim(MyWorkBook.WorkSheets[1].Cells[i,1]))+''','''+uppercase(Trim(MyWorkBook.WorkSheets[1].Cells[i,2]))+''','''+uppercase(Trim(MyWorkBook.WorkSheets[1].Cells[i,5]))+''',cast('''+uppercase(Trim(MyWorkBook.WorkSheets[1].Cells[i,6]))+''' as int))');
              ADOQuery1.ExecSQL; 
    i:=i+1;                                                   
    end
    ...
      

  7.   

    注意一个excel大概可以放6w多条数据。
      

  8.   

    觉得tengwei99说的很值得参考,如果要判断为空与否,Excel中的一个Sheet就有6w多条数据(包括空的),要判断起来,很耗时!
      

  9.   

    几个建议:while i<j+1 do
    begin
    ADOQuery1.ConnectionString:=connetstr;这个太浪费了。应该是在循环外设置ConnectionString比较好;ADOQuery1.SQL.Add('insert into B(BID,Bcaption,DFF,TF)');
    ADOQuery1.SQL.Add('values('''+uppercase(Trim(MyWorkBook.WorkSheets[1].Cells[i,1]))+''','''+uppercase(Trim(MyWorkBook.WorkSheets[1].Cells[i,2]))+''','''+uppercase(Trim(MyWorkBook.WorkSheets[1].Cells[i,5]))+''',cast('''+uppercase(Trim(MyWorkBook.WorkSheets[1].Cells[i,6]))+''' as int))');上面的方法在数据量比较大的时候会效率很低。所以建议采用存储过程+参数传递的方法。其它就没有什么好建议的了。
      

  10.   

    我现在暂时这样处理,加一个Edit1,给用户去输入数量,这个数量跟Excel表的有数据的数量必须一样! J:=MyWorkBook.ActiveSheet.UsedRange.Rows.Count;
    改成
    J:=StrToInt(Trim(Edit1.Text));其他代码按原来的做!
    执行速度也很快,完全可以进行操作!就是Edit1里值必须跟Excel工作表的数据的Count是一样的!
    这点操作的人必须注意!