4 votos

¿Cómo puedo invertir mi selección en Microsoft Excel utilizando AppleScript? (selección en sí, no propiedades de la selección)

Me gustaría invertir mi selección con AppleScript. Esto es análogo a la funcionalidad de Adobe Photoshop (y otros productos de Adobe) "Invertir la selección (Ctrl/Cmd + I para deseleccionar lo que estaba previamente seleccionado y seleccionar lo que no estaba seleccionado)"

  1. I puede seleccionar un grupo de celdas con AppleScript.
  2. I puede obtener el rango seleccionado con AppleScript
  3. I puede bucle de celdas seleccionadas
  4. Yo como seleccionar todas las celdas que no están seleccionadas actualmente

Código

tell application "Microsoft Excel"
    repeat with item_cell from 1 to count large of selection -- all cells in selection
        --do stuff with selected cells
    end repeat

    -- index of selected cells technique, not sure whether helpful
    set sel_range to selection
    tell selection to set {rowIndex, columnIndex, rowCount, columnCount} to {get first row index of sel_range, get first column index of sel_range, get count rows of sel_range, get count columns of sel_range}
end tell

Células originalmente seleccionadas

enter image description here

Selección deseada

(Se seleccionan todas las celdas de la hoja que no estaban seleccionadas originalmente) enter image description here

1voto

Monomeeth Puntos 139

He estado trabajando en esta cuestión durante un tiempo y, al chocar con un muro de ladrillos, decidí intentar que funcionara utilizando Visual Basic en su lugar. Espero que al hacer esto sea más fácil conseguir el código correcto dentro de AppleScript, así que comparto el código de Visual Basic por si ayuda a alguien más a conseguir una versión de AppleScript que funcione - ¡no es que me haya rendido todavía! :)

Sub InvertSheet()

Set s1 = Selection
Set s2 = Range("A1:Z100")
Set sinv = Nothing

For Each s In s2
If Intersect(s, s1) Is Nothing Then
If sinv Is Nothing Then
Set sinv = s
Else
Set sinv = Union(sinv, s)
End If
End If
Next

If sinv Is Nothing Then
Else
sinv.Select
End If
End Sub

NOTAS:

  • Me he encontrado con un problema, y es que no he podido encontrar la manera de que esto se aplique a toda la hoja sin que Excel se cuelgue durante periodos de tiempo extremadamente largos (probablemente porque tiene que comprobar 1.048.576 filas y 16.384 columnas) para hacerlo.
  • Para evitar este problema he utilizado Set s2 = Range("A1:Z100") para limitar el área de la hoja a la que se aplica el código al rango A1:Z100. Sin embargo, esto puede cambiarse para adaptarse a un área mayor si es necesario.
  • Imagino que intentar cubrir toda la hoja será un problema también dentro de AppleSCript.

1voto

macmadness86 Puntos 106

Finalmente, tengo una solución. Enormes gracias a Monomeeth por la versión VBA que me puso en el camino correcto. (Y hacer que esto también sea posible en Windows)

Funciona de forma similar a la versión de Monomeeth. Tiene un rango considerado por razones de rendimiento. Establézcalo cambiando esta línea en consecuencia:

set range_considered to range "A1:Z100" of active sheet

Aquí está:

-- use "intersect" to test whether the considered area overlaps with the selected area
-- use union to append non-selected cells to a new range

tell application "Microsoft Excel"
    set screen updating to false -- optimize performance
    --tell active sheet of active workbook
    set range_considered to range "A1:Z100" of active sheet
    set range_selected to selection
    set range_new_selection to "Nothing"

    -- setup ref vars for selection
    tell selection to set {range_selected_row_index, range_selected_column_index, range_selected_row_count, range_selected_column_count} to {get first row index of selection, get first column index of selection, get count rows of selection, get count columns of selection}
    -- setup ref vars for considered
    tell selection to set {range_considered_row_index, range_considered_column_index, range_considered_row_count, range_considered_column_count} to {get first row index of range_considered, get first column index of range_considered, get count rows of range_considered, get count columns of range_considered}

    -- go column by column and iterate each row in each column
    repeat with considered_col_step from range_considered_column_index to range_considered_column_count
        repeat with considered_row_step from range_considered_row_index to range_considered_row_count
            set range_this_cell to range (get address row considered_row_step of column considered_col_step of active sheet) of active sheet
            log range_selected
            try
                set range_test to intersect range1 range_this_cell range2 range_selected -- test for intersection with selected
                (*use try to detect error. Will fail if cell is within selection*)
                log "TRUE Intersected"
            on error
                (*Create or append to range_new_selection*)
                log "FALSE intersected"
                if range_new_selection is "Nothing" then
                    set range_new_selection to range_this_cell
                else
                    set range_new_selection to union range1 range_new_selection range2 range_this_cell
                end if
            end try
        end repeat
    end repeat
    try
        select range_new_selection
    on error
        log "Could not select new range."
    end try
    set screen updating to true -- optimize performance
end tell

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X