Soy nuevo en VBA y he estado buscando en línea y viendo tutoriales de YouTube, pero tengo problemas para escribir el código a continuación y hacer que funcione. Estoy trabajando con dos hojas de cálculo en el mismo libro de trabajo. Se agradecería cualquier ayuda. Por favor, comprenda que soy un principiante y necesito orientación. No hay necesidad de comentarios despectivos. He estado trabajando en esto durante más de dos semanas y no puedo entenderlo.

Tengo una hoja con la etiqueta "plantilla" que tiene el nombre de un estudiante en la celda A1. El nombre del estudiante cambiará pero la ubicación del nombre siempre estará en esta celda.

En mi segunda hoja de cálculo denominada "Evaluaciones", necesito ejecutar un ciclo en la columna A para encontrar el nombre del estudiante.

Si se encuentra el nombre del estudiante durante esa búsqueda, entonces necesito copiar cualquier información en la Columna AC que corresponda a las filas donde se encuentra el nombre.

Todo lo que se copia debe pegarse en mi primera "plantilla" de hoja de cálculo en la fila 61-70 de la columna A y para que se agreguen automáticamente las filas adicionales necesarias para adaptarse a las filas copiadas.

Option Explicit

Sub Test()
Dim StudentName As String '(StudentName is a unique identifier)
Dim Template As Worksheet '(this is the worksheet I'm pulling data into)
Dim Evaluations As Worksheet '(this is the sheet I'm pulling data from)
Dim finalrow As Integer
Dim i As Integer
Set Template = Sheets("Evaluation Form Template")
Set Evaluations = Sheets("Evaluations")

'this is where i want to cut and paste to
'getting an error here
 Range("A61:A70").ClearContents

'This is the value I am looking for: getting an error here
 StudentName = Sheets("Template").Range("A1").Value

 'this is the sheet I am searching my value in Column A
 finalrow = Sheets("Evaluations").Range("A10000").End(xlUp).Row

 'once it runs the loop if the student name was found in Column A then I   need it to copy and paste any information in Column 29/AC
'into my Template sheet in Column A row 61
 For i = 2 To finalrow
 If Cells(i, 1) = StudentName Then
 Range(Cells(i, 29)).Copy
 Sheets("template").Range("A61").End(xldown).Offset(1, 0).PasteSpecialxlPasteFormulasAndNumberFormats
 End If
 Next i

 End Sub
1
Aggie04 17 feb. 2018 a las 01:42

2 respuestas

La mejor respuesta

1) Has declarado tus sábanas pero no las usas.

Set Template = ThisWorkbook.Sheets("Evaluation Form Template")
Set Evaluations = ThisWorkbook.Sheets("Evaluations")

Luego escribe - Template.Range("A1").Value
En lugar de - Sheets("Template").Range("A1").Value

Creo que recibe un error porque no ha especificado la hoja:

Escribir: Template.Range("A61:A70").ClearContents
En lugar de - Range("A61:A70").ClearContents

2) Si el nombre del estudiante es único, debe usar el método Range.Find en lugar de recorrer todas las filas. Será mucho más rápido.

Devuelve un objeto Range que representa la primera celda donde esa se encuentra la información. https://msdn.microsoft. com / en-us / vba / excel-vba / articles / range-find-method-excel

Dim name_rg As range

{...}

' ~ Search name of the student ~
Set name_rg = Evaluation.columns(1).Find(Template.[a1])

If Not name_rg Is Nothing then
   Template.[a61] = Evaluation.cells(name_rg.row, 29)
Else
   MsgBox("No student found")
End If

3) Al principio, agregue la línea a continuación, hará que su código sea mucho más rápido

Application.ScreenUpdating = False

4) Al final de su código, borre la memoria y regrese la actualización de la pantalla a True:

Set name_rg = Nothing
Set Template = Nothing
Set Evaluations = Nothing

Application.ScreenUpdating = True

~ Tu código debería verse así:

 Option Explicit

 Sub Test()
    Application.ScreenUpdating = False

    Dim StudentName As String
    Dim Template As Worksheet 
    Dim Evaluations As Worksheet 
    Dim finalrow As Integer
    Dim i As Integer
    Dim name_rg As range

    Set Template = ThisWorkbook.Sheets("Evaluation Form Template")
    Set Evaluations = ThisWorkbook.Sheets("Evaluations")

    Template.Range("A61:A70").ClearContents

    ' ~ Search name of the student ~
    Set name_rg = Evaluation.columns(1).Find(Template.[a1])

    If Not name_rg Is Nothing then
       Template.[a61] = Evaluation.cells(name_rg.row, 29)
    Else
       MsgBox("No student found")
    End If

    Set name_rg = Nothing
    Set Template = Nothing
    Set Evaluations = Nothing

    Application.ScreenUpdating = True
End Sub

Editar:
En caso de que haya varios estudiantes en Template, deberá realizar una For Loop en lugar de utilizar la solución Range.Find. Debajo de las modificaciones:

Sub Test()
    Application.ScreenUpdating = False

    Dim Template As Worksheet
    Dim Evaluations As Worksheet
    Dim Nb_Rows As Integer
    Dim i As Integer
    Dim x, Row as Integer

    Set Template = ThisWorkbook.Sheets("Evaluation Form Template")
    Set Evaluations = ThisWorkbook.Sheets("Evaluations")

    Template.Range("A61:A70").ClearContents

    ' the table in this example starts in A1
    ' please mind that blank lines might cause issues
    Nb_Rows = Evaluations.[a1].CurrentRegion.Rows.Count
    Row = 61 ' first row to input results in Template
    x = 0    ' needed to increment

    For i = 1 to Nb_Rows
        If Evalutations.Cells(i, 1) = Template.[a1] Then
            Template.cells(Row + x, 1) = Evalutations.Cells(i, 29)
            x = x + 1
        End If
    Next i

    Set Template = Nothing
    Set Evaluations = Nothing

    Application.ScreenUpdating = True
End Sub
0
smallwat3r 19 feb. 2018 a las 18:15

Hay un par de cosas que puedo ver que podrían ser un problema. Está configurando algunas variables para las hojas de trabajo pero no las está usando. Por ejemplo, está intentando borrar el contenido de la hoja de plantilla de esta manera:

Template.Range("A61:A70").ClearContents

Puede obtener el nombre del estudiante así:

StudentName = Template.Range("A1").Value
'or shorter version
StudentName = Template.[A1]

En su bucle, en qué hoja está bucleando:

If Evaluations.Cells(i,1) = StudentName then

Y, por último, no debería tener que copiar, puede establecer un valor igual al otro para completar la celda de esta manera:

Template.Range("A61").End(xldown).Offset(1,0) = Evaluations.Range(Cells(i,1),Cells(i,29))

La conclusión de esto es asegurarse de calificar completamente dónde obtiene información y dónde la envía. Una última cosa, no estoy seguro de si esto debe ser así, pero está usando Evaluation Form Template como hoja de trabajo para Template pero usando el nombre Template como referencia en otros lugares. ¿Deberían ser iguales?

0
R. Roe 16 feb. 2018 a las 23:14