Vba 将信息列导出到新图纸

Vba 将信息列导出到新图纸,vba,excel,Vba,Excel,我正在尝试创建一个学校成绩单,其中可以在输入表上输入成绩(下拉菜单中的a、B、C和D),然后将与不同学生相关的信息导出到单独的表中 我发现这个宏(如下)用于将信息从输入工作表导出到工作簿中的单独工作表,但问题是它可以在行而不是列中工作。它采用列A(比如A3)中的名称,基于该名称创建一个工作表,并根据输入到模块中的范围变量从第3行导出信息 我想做的是从一行而不是一列中获取名称,然后将名称下方的信息导出到单独的工作表中(名称是新工作表的标题)。所以,正如你在截图中所看到的,我的学生的名字从D7到Q7

我正在尝试创建一个学校成绩单,其中可以在输入表上输入成绩(下拉菜单中的a、B、C和D),然后将与不同学生相关的信息导出到单独的表中

我发现这个宏(如下)用于将信息从输入工作表导出到工作簿中的单独工作表,但问题是它可以在行而不是列中工作。它采用列A(比如A3)中的名称,基于该名称创建一个工作表,并根据输入到模块中的范围变量从第3行导出信息

我想做的是从一行而不是一列中获取名称,然后将名称下方的信息导出到单独的工作表中(名称是新工作表的标题)。所以,正如你在截图中所看到的,我的学生的名字从D7到Q7,第一个学生的成绩从D8到D63

[截图][1]

我尝试将所有vcol命令更改为行命令,反之亦然,但我似乎无法调试它。我对成为一名更好的程序员很感兴趣,但我必须承认我基本上是一名新手。有什么建议吗

Sub parse_data()
    Dim lr As Long
    Dim ws As Worksheet
    Dim vcol, i As Integer
    Dim icol As Long
    Dim myarr As Variant
    Dim title As String
    Dim titlerow As Integer
    vcol = 1
    Set ws = Sheets("Sheet1")
    lr = ws.Cells(ws.Rows.Count, vcol).End(xlUp).Row
    title = "A1:C1"
    titlerow = ws.Range(title).Cells(1).Row
    icol = ws.Columns.Count
    ws.Cells(1, icol) = "Unique"
    For i = 2 To lr
        On Error Resume Next
        If ws.Cells(i, vcol) <> "" And Application.WorksheetFunction.Match(ws.Cells(i, vcol), ws.Columns(icol), 0) = 0 Then
            ws.Cells(ws.Rows.Count, icol).End(xlUp).Offset(1) = ws.Cells(i, vcol)
        End If
    Next
    myarr = Application.WorksheetFunction.Transpose(ws.Columns(icol).SpecialCells(xlCellTypeConstants))
    ws.Columns(icol).Clear
    For i = 2 To UBound(myarr)
        ws.Range(title).AutoFilter Field:=vcol, Criteria1:=myarr(i) & ""
       If Not Evaluate("=ISREF('" & myarr(i) & "'!A1)") Then
            Sheets.Add(after:=Worksheets(Worksheets.Count)).name = myarr(i) & ""
        Else
            Sheets(myarr(i) & "").Move after:=Worksheets(Worksheets.Count)
        End If
        ws.Range("A" & titlerow & ":A" & lr).EntireRow.Copy Sheets(myarr(i) & "").Range("A1")
        Sheets(myarr(i) & "").Columns.AutoFit
    Next
    ws.AutoFilterMode = False
    ws.Activate
End Sub
子解析_数据()
变暗lr为长
将ws设置为工作表
Dim vcol,i作为整数
如长
Dim myarr作为变异体
将标题设置为字符串
作为整数的Dim titlerow
vcol=1
设置ws=图纸(“图纸1”)
lr=ws.Cells(ws.Rows.Count,vcol).End(xlUp).Row
title=“A1:C1”
titlerow=ws.Range(title).Cells(1).Row
icol=ws.Columns.Count
ws.Cells(1,icol)=“唯一”
对于i=2至lr
出错时继续下一步
如果ws.Cells(i,vcol)“”和Application.WorksheetFunction.Match(ws.Cells(i,vcol),ws.Columns(icol),0)=0,则
ws.Cells(ws.Rows.Count,icol).End(xlUp).Offset(1)=ws.Cells(i,vcol)
如果结束
下一个
myarr=Application.WorksheetFunction.Transpose(ws.Columns(icol).SpecialCells(xlCellTypeConstants))
ws.Columns(icol).清除
对于i=2到UBound(myarr)
ws.Range(title).AutoFilter字段:=vcol,标准1:=myarr(i)&“”
如果不进行评估(“=ISREF(”&myarr(i)&“!A1)”),则
Sheets.Add(之后:=工作表(Worksheets.Count)).name=myarr(i)和“”
其他的
工作表(myarr(i)和“”)。移动后:=工作表(Worksheets.Count)
如果结束
ws.Range(“A”&标题栏&“:A”&标题栏).EntireRow.Copy图纸(myarr(i)&“).Range(“A1”)
图纸(myarr(i)和“”).Columns.AutoFit
下一个
ws.AutoFilterMode=False
ws.Activate
端接头

虽然可能有一些“按行过滤”的方法,但我还是会使用
字典
的方法

Option Explicit

Sub parse_data()
    Dim studsSht As Worksheet
    Dim cell As Range
    Dim stud As Variant

    Set studsSht = Worksheets("Sheet1") '<--| change "Sheet1" to your actual students grades sheet
    With CreateObject("Scripting.Dictionary") '<--| instantiate a Dictionary object
        For Each cell In studsSht.Range("D7:Q7").SpecialCells(xlCellTypeConstants, xlTextValues) '<--| loop through students names (change "D7:Q7" to your actual range with students names)
            .item(cell.Value) = .item(cell.Value) & cell.EntireColumn.Address(False, False) & "," '<--| add or update the dictionary entry whose key is the current student name with its corresponding column address
        Next
        For Each stud In .keys '<--| loop through unique students names
            Intersect(studsSht.UsedRange, studsSht.Range(Left(.item(stud), Len(.item(stud)) - 1))).Copy Destination:=GetSheet(CStr(stud)).Range("A1") '<--| copy its columns to correspondingly named sheet starting from cell A1
        Next
    End With

    studsSht.Activate
End Sub

Function GetSheet(shtName As String) As Worksheet
    On Error Resume Next
    Set GetSheet = Worksheets(shtName)
    If GetSheet Is Nothing Then
        Set GetSheet = Sheets.Add(after:=Worksheets(Worksheets.count))
        GetSheet.Name = shtName
    End If
End Function
选项显式
子解析_数据()
Dim studsSht作为工作表
暗淡单元格作为范围
变型尺寸螺柱

Set studsSht=Worksheets(“Sheet1”)”代码似乎比您的规范要求的更为华丽,因此我在这里的回答中对其进行了简化,使其更易于理解。第一个for循环只是删除标题中的重复项(在您的情况下,如果您有多个学生同名,它只会为该名称创建一个新的工作表)

因为您的用例似乎要求数据中的每个学生都有一个唯一的标识符,所以我删除了该标识符(以及相关代码),以使您更简单。下面这个简单的子程序应该可以为一定数量的学生解决问题。如果你打算将来扩展学生,那么进入并使该部分变得动态很容易,但现在你只需编辑
Set studentsRange=masterSheet.range(“D7:Q7”)
中的范围,以始终与学生的姓名所在位置相对应

Sub CreateIndividualReportCards()
    Dim masterSheet As Worksheet
    Set masterSheet = Sheets("Sheet1") 'This is the title of the sheet where your bulk data is
    Dim studentsRange As Range
    Set studentsRange = masterSheet.Range("D7:Q7") 'This is the range of your headings, in your case student names

    Dim i As Integer
    For i = 1 To studentsRange.Columns.Count
        If Not Evaluate("=ISREF('" & studentsRange.Cells(i) & "'!A1)") Then 'This checks to see if a sheet for the student already exists
            Sheets.Add(after:=Worksheets(Worksheets.Count)).Name = studentsRange.Cells(i) & ""
        End If
        Sheets(studentsRange.Cells(i) & "").Columns.ClearContents 'In case the sheet already exists with old data, this line clears that old data and in order to repopulate with the new data from the masterSheet
        studentsRange.Cells(i).EntireColumn.Copy Sheets(studentsRange.Cells(i) & "").Range("A1") 'This copies the student's grades to the new sheet
    Next i

    masterSheet.Activate
End Sub

为了避免人们在回答您的问题之前必须访问(可能感染病毒的)第三方网站,请将链接末尾的内容粘贴到问题本身。(如果它是一个图像,那么它将被托管在一个网站上,在这个网站上,即使第三方网站不再存在,该图像仍将对该问题的未来读者可用。)@a.S.H-我会的,但我不知道该网站是什么,所以我不想去那里复制该图像(或其他)。我认为OP需要将图像放入问题中(因此在imgur的SO部分托管),然后我们可以编辑问题以将其内联(如果合适);这很有效。这一行中有多少学生没有区别,它创建了正确数量的工作表,没有错误消息。但是,它不能保留单元格的宽度。无论如何,我忘了提到,除了每个学生的相关信息要放到另一张纸上,我还想把输入页(即A1到C63)上的“通用”信息放到每张纸上,这样分数才有意义。要让这一切顺利进行,要求是否过高?我不是真的在一个宏中有多个函数。欢迎你。由于我的答案解决了您的原始问题,您可能希望通过单击答案旁边的复选标记将其从灰色变为已填写来将其标记为已接受。非常感谢。至于其他问题,让我同时考虑一下……对不起,是的。当我去寻找答案时,我发现有人用蜱来回应我。干得好。非常感谢。@Davie,你标记为接受了另一个答案。不管怎样,如果你真的选择了这个,那也没关系。它们都很好用。有趣的是,不同的代码(看起来完全不同的代码)可以执行相同的功能。我想我更喜欢这样一个事实:我可以将这个宏应用于我的任何类,而不必编辑宏。唯一的问题是,我可以看看另一个宏,了解它是如何工作的。你的宏刚刚为我做了很多研究!但我想这就是我来这里的目的。我没想到会有这么快的反应。谢谢