visibles variable valor seleccionar rango primera obtener macro filtrar encontrar después desde datos cómo con celdas celda activa excel vba excel-vba email filter

excel - variable - seleccionar la primera celda de un rango vba



VBA: seleccione la primera celda filtrada y luego avance a la siguiente (2)

Creo que la propiedad Hidden de un rango es lo que quieres. El siguiente código funcionó para mí:

Dim row As Range For Each row In Range("MyTable").Rows If not row.EntireRow.Hidden Then '''''' DO STUFF '''''' End If Next

Siempre he encontrado que usar un bucle For Each es una forma mucho más limpia de iterar a través de datos en una hoja de Excel. "MyTable" fue el nombre que le di al rango de interés, pero si lo prefiere, puede ingresar a los límites del rango como Range("A1:D4") . Aunque creo que es una mejor práctica usar rangos con nombre ya que hace que tu código sea más legible.

EDITAR: Para dirigir tu comentario ...

Si inserta una fila en el medio de un rango con nombre, los límites del rango se expanden automáticamente. Aunque si su tabla va a ser el único dato en la hoja de cálculo, también puede usar la propiedad UsedRange de un objeto de hoja de cálculo. Por ejemplo:

Dim row As Range For Each row In Worksheets("MySheet").UsedRange.Rows If not row.EntireRow.Hidden Then '''''' DO STUFF '''''' End If Next

Si todo lo que tienes es la primera fila de la tabla, puedes expandir este rango a la tabla completa usando:

dim FirstRow as Range dim LastRow as Range dim myTable as Range set FirstRow = Range("A1:B1") set LastRow = FirstRow.End(xlDown) set myTable = Range(FirstRow, LastRow)

Y luego use el mismo bucle For Each que antes. ¡Espero que esto ayude!

Lo que quiero hacer me parece bastante simple, pero no puedo encontrar la forma de hacerlo. Tengo una hoja de cálculo Excel que tiene muchos detalles de contacto, por ejemplo:

A B C D E 1 Select who you would to like to email: * Drop down list * 2 Name: Company: Role: Email Address1: Email Address2: 3 Michael Jackson Jackson 5 Singer [email protected] [email protected] 4 Brian May Queen Guitarist [email protected] [email protected] 5 Kurt Cobain Nirvana Singer [email protected] [email protected] 6 Freddie Mercury Queen Singer [email protected] [email protected] 7 Pat Smear Nirvana Guitarist [email protected] [email protected]

Un usuario selecciona qué dirección de correo electrónico desea enviar por correo electrónico utilizando la lista desplegable en D1 , por ejemplo, correo electrónico 1, y luego ejecuta una macro que obtiene los destinatarios del correo electrónico en esa columna. Este bit está bien y lo tengo funcionando. El problema es que cuando un usuario aplica un filtro, digamos todos los guitarristas, seleccionará la primera fila filtrada ( C4 ) y luego irá a la siguiente fila en lugar de a la siguiente fila filtrada, por lo que iría a C5 .

Esta es una adaptación del código que estoy usando actualmente:

Sub SendEmail() Dim objOutlook As Object Dim objMail As Object Dim RowsCount As Integer Dim Index As Integer Dim Recipients As String Dim Category As String Dim CellReference As Integer Set objOutlook = CreateObject("Outlook.Application") Set objMail = objOutlook.CreateItem(0) RowsCount = ActiveSheet.AutoFilter.Range.Columns(1).SpecialCells(xlCellTypeVisible).Cells.Count - 1 Category = Range("D1") Dim RowLimit As String If Category = "Email Address1" Then CellReference = 4 ElseIf Category = "Email Address2" Then CellReference = 5 End If Index = 0 While Index < RowsCount Set EmailAdrs = ActiveSheet.AutoFilter.Range.Offset(1).SpecialCells(xlCellTypeVisible).Cells(1, CellReference).Offset(0 + Index, 0) Recipients = Recipients & EmailAdrs.Value & ";" Index = Index + 1 Wend With objMail .To = Recipients .Subject = "This is the subject" .Display End With Set objOutlook = Nothing Set objMail = Nothing End Sub

Pero esto solo seleccionará la primera celda filtrada y luego cualquiera que sea la celda debajo de eso.

He intentado muchas ideas diferentes, como pasar por las filas que están ocultas:

While Index < RowsCount Do While Rows(ActiveCell.Row).Hidden = True ''ActiveCell.Offset(1).Select Set EmailAdrs = ActiveSheet.AutoFilter.Range.Offset(1).SpecialCells(xlCellTypeVisible).Cells(1, CellReference).Offset(0 + Index, 0) Recipients = Recipients & EmailAdrs.Value & ";" Index = Index + 1 ActiveCell = ActiveCell.Offset(0 + Index, 0).Select Loop Wend

He intentado atravesar solo las celdas visibles.

He intentado las ideas de otras personas de otra pregunta de StackOverflow ( VBA Ir a la siguiente celda filtrada ):

If ActiveSheet.FilterMode = True Then With ActiveSheet.AutoFilter.Range For Each a In .Offset(1).Resize(.Rows.Count).SpecialCells(xlCellTypeVisible).Areas Recipients = Recipients & a(1, CellReference) & ";" Next End With MsgBox Replace(Recipients, ";;", vbNullString) End If

Y:

Dim Rng As Range If Category = Range("S2") Then CellReference = 10 ''Set your range Set Rng = Range("A1:B2") ElseIf Category = Range("S3") Then CellReference = 14 ''Set your range Set Rng = Range("C1:D2") ElseIf Category = Range("S4") Then CellReference = 18 ''Set your range Set Rng = Range("F1:G2") ElseIf Category = Range("S5") Then CellReference = 16 ''Set your range Set Rng = Range("H1:J2") End If For Each mCell In ThisWorkbook.Sheets("YourSheetName").Range(Rng).SpecialCells(xlCellTypeVisible) ''Get cell address mAddr = mCell.Address ''Get the address of the cell on the column you need NewCellAddr = mCell.Offset(0, ColumnsOffset).Address ''Do everything you need Next mCell

Y varias otras ideas y cosas de otras páginas web, pero parece que no funcionan.

¿Puede alguien ayudarme y tenga en cuenta que soy nuevo en VBA, así que no tengo mucho conocimiento.


Prueba este código:

Sub SendEmail() Dim objOutlook As Object Dim objMail As Object ''Dim RowsCount As Integer ''Dim Index As Integer Dim Recipients As String Dim Category As String Dim CellReference As Integer Dim RowLimit As String ''New variables. Dim firstRow As Long Dim lastRow As Long Dim cell As Excel.Range Dim row As Long Set objOutlook = CreateObject("Outlook.Application") Set objMail = objOutlook.CreateItem(0) Category = Range("D1") If Category = "Email Address1" Then CellReference = 4 ElseIf Category = "Email Address2" Then CellReference = 5 End If With ActiveSheet ''Find the first and last index of the visible range. firstRow = .AutoFilter.Range.Offset(1).SpecialCells(xlCellTypeVisible).row lastRow = .Cells(.Rows.Count, 1).End(xlUp).row ''Iterate through all the rows between [firstRow] and [lastRow] established before. ''Some of those rows are hidden, but we will check it inside this loop. For row = firstRow To lastRow Set cell = .Cells(row, CellReference) ''We are checking here if this row is hidden or visible. ''Note that we cannot check the value of property Hidden of a single cell, ''since it will generate Run-time error ''1004'' because a single cell cannot be ''hidden/visible - only a whole row/column can be hidden/visible. ''That is why we need to refer to its .EntireRow property first and after that we ''can check its .Hidden property. If Not cell.EntireRow.Hidden Then ''If the row where [cell] is placed is not hidden, we append the value of [cell] ''to variable Recipients. Recipients = Recipients & cell.Value & ";" End If Next row End With With objMail .To = Recipients .Subject = "This is the subject" .Display End With Set objOutlook = Nothing Set objMail = Nothing End Sub