Excel 用VBA提取数据

一个工作薄有100多个表格,格式都是一样的。能不能提取符合要求的数据的,如果能解决的话,会加分的。
要求:
1、需要提取的数据是每个表的B-K列,提取的关键词是L列的√,将L列没有打”√“的B-K列的数据填充到数据提取的B-K列
如图1的表,一个有15组数据,符合提取的数据有11条,所以将L列没有打”√“数据提取的B-K列填充到数据提取的B-K列,如图2
2;当然,这些都是我的想法,可能是不能实现的,如果真的不可能的事,我也没什么
如果真能解决了,就最好不过

图1

图2

原件”http://pan.baidu.com/s/1pJx4XbP
有问题可以提问

 1、汉字在前,数字在后面的情形。可以用MID,min, find三个函数来实现提取里面的数字。如图:在B2输入“=MID(A1,MIN(FIND({0,1,2,3,4,5,6,7,8,9},A1&“0123456789”)),20)”

 2 、把单元格里面所有的数字都提出来。可以使用宏。先打开VBA编辑器。工具——宏——visual basic 编辑器

 3、在编辑器里点击插入——模块。在模块那里输入如下代码:

  Function zzsz(xStr As String) As StringDim i As IntegerFor i = 1 To Len(xStr)If IsNumeric(Mid(xStr, i, 1)) Then zzsz = zzsz & Mid(xStr, i, 1)NextEnd Function

  4、回到工作表,在B2单元格那里输入“=zzsz(A2)”。就可以用VBA把A2单元格里所有的数字都提取出来了,如图所示。



 Excel怎么只提取表格中的数字

  5、指定从第几个数组提取开始。也就是说在不连续的那些数字中,从第几次出现的数组开始提取。同样在模块那里输入如下代码:

  Function GetNums(rCell As Range, num As Integer) As StringDim Arr1() As String, Arr2() As StringDim chr As String, Str As StringDim i As Integer, j As IntegerOn Error GoTo line1

  Str = rCell.TextFor i = 1 To Len(Str)chr = Mid(Str, i, 1)If (Asc(chr) 《 48 Or Asc(chr) 》 57) ThenStr = Replace(Str, chr, “ ”)End IfNext

  Arr1 = Split(Trim(Str))ReDim Arr2(UBound(Arr1))For i = 0 To UBound(Arr1)If Arr1(i) 《》 “” ThenArr2(j) = Arr1(i)j = j + 1End IfNext

  GetNums = IIf(num 《= j, Arr2(num - 1), “”)line1:End Function


 6、在回到单元格那里输入“=Getnums(A3,2)”就可以提取第几次出现的数组了,如图所示。

温馨提示:内容为网友见解,仅供参考
第1个回答  2014-07-07
Sub 提取数据()
Application.ScreenUpdating = False '这句将极大提升效率
n = 1  '数据提取表从第一行开始填充数据
For i = 3 To Sheets.count '从第3个表开始直到最后1个表
    For j = 4 To 2000  '每个表的数据从第四行开始
        If Sheets(i).Cells(j, "C") = "" Then Exit For 'C列数据为空,该表数据提取完毕
        If Sheets(i).Cells(j, "L") <> "√" Then
            Sheets(1).Range("B" & n & ":K" & n).Value = Sheets(i).Range("B" & j & ":K" & j).Value
            n = n + 1
        End If
    Next
Next
Application.ScreenUpdating = True
End Sub

追问

你好,基本可以实现了,因上传的文件和实际的有少许出入。现实的表,√在m列,将符合的要求的数据C-L列提取出来,应该怎么改

追答Sub 提取数据()
Application.ScreenUpdating = False '这句将极大提升效率
n = 1  '数据提取表从第一行开始填充数据
For i = 3 To Sheets.count '从第3个表开始直到最后1个表
    For j = 4 To 5000  '每个表的数据从第四行开始
        If Sheets(i).Cells(j, "D") = "" Then Exit For 'D列数据为空,该表数据提取完毕
        If Sheets(i).Cells(j, "M") <> "√" Then
            Sheets(1).Range("C" & n & ":L" & n).Value = Sheets(i).Range("C" & j & ":L" & j).Value
            n = n + 1
        End If
    Next
Next
Application.ScreenUpdating = True
End Sub

本回答被网友采纳
第2个回答  2014-07-07

附件做好的,

有问题追问

 

Alt +F8运行

追问

你好,基本可以实现了,因上传的文件和实际的有少许出入。现实的表,√在m列,将符合的要求的数据C-L列提取出来,应该怎么改

追答为什么不放实际格式一致的呢?

Sub xxx()
Sheets("数据提取").Range("C5:L10000").ClearContents
 Dim i As Worksheet
  For Each i In ThisWorkbook.Sheets
   If i.Name <> "数据提取" Or i.Name <> "总表" Then
    lr = i.Cells(65536, 3).End(xlUp).Row
      For j = 5 To lr
        If i.Cells(j, "M") <> "√" Then  'M列
         b = Sheets("数据提取").Cells(65536, 3).End(xlUp).Row + 1
         i.Range("C" & j & ":L" & j).Copy Sheets("数据提取").Cells(b, "C")     'C:L列
        End If
      Next
     End If
   Next
End Sub

追问

不好意思,现在上传了原文件,你帮我调试一下吧
http://pan.baidu.com/s/1hqiknha

追答

好了

追问

最后一问,没什么就选择你了,真的麻烦你啦

我这里有两个文件,内容差不多,就是√在所在位置不一样,

用你的代码导入我本地的,居然出错了,你帮我试一下吧,万分感谢

http://pan.baidu.com/s/1rjUsY

我自己试了一下,可以了,那个文件名能不能改为显示C1的那个值啊

追答

Sheets("数据提取").Cells(b, "M") = i.Name
改为 :

Sheets("数据提取").Cells(b, "M") = i.range("C1")

追问

你好,这个代码已指定了不运行的工作表,但当我运行时,还是会将整个工作薄提取,帮我看看吧,那些指定不读取的代码应该怎么表示,麻烦了

本回答被提问者采纳
第3个回答  2014-07-07
你的前两个表是不是固定的名称,而且是不需要提取的?追问

是的,其他的都要,前两个表是固定的名称
,不用提取

追答

Sub test()
Dim temp, mytemp
Dim r As Long, myr As Long, rt As Long
'Dim mysheet As Sheets
For Each mysheet In ActiveWorkbook.Worksheets
r = mysheet.Range("C65536").End(xlUp).Row
If (mysheet.Name "数据提取" Or mysheet.Name "总表") And r > 4 Then

temp = mysheet.Range("C5:M" & r).Value
ReDim mytemp(1 To r - 4, 1 To 11)
myrt = 0
For rt = 1 To r - 4
If temp(rt, 11) "√" Then
myrt = myrt + 1
For c = 1 To 11
mytemp(myrt, c) = temp(rt, c)
Next c
End If
Next rt
If myrt > 0 Then
r = Sheets("数据提取").Range("C65536").End(xlUp).Row
Sheets("数据提取").Range("C" & r + 1 & ":M" & myrt + r + l) = mytemp
End If
End If
Next
End Sub

追问

问过了,运行后,那些不符合要求的也提取了(就是全部都提取出来了)

追答

你打"√" 不是在M列么,从C列到M列为共11列的嘛,如果不是就改一下列,以及相应的列号就是了!
是看到你后面的追问后修改了列号

Sub test()
Dim temp, mytemp
Dim r As Long, myr As Long, rt As Long
'Dim mysheet As Sheets
For Each mysheet In ActiveWorkbook.Worksheets
r = mysheet.Range("C65536").End(xlUp).Row
If (mysheet.Name "数据提取" Or mysheet.Name "总表") And r > 4 Then

temp = mysheet.Range("C5:M" & r).Value'M为你数据的最后列
ReDim mytemp(1 To r - 4, 1 To 11)'11为对应的列号,后面的11也相应的修改
myrt = 0
For rt = 1 To r - 4
If temp(rt, 11) "√" Then
myrt = myrt + 1
For c = 1 To 11
mytemp(myrt, c) = temp(rt, c)
Next c
End If
Next rt
If myrt > 0 Then
r = Sheets("数据提取").Range("C65536").End(xlUp).Row
Sheets("数据提取").Range("C" & r + 1 & ":M" & myrt + r + l) = mytemp
End If
End If
Next
End Sub

相似回答