Come posso invertire la selezione in Microsoft Excel utilizzando AppleScript? (selezione stessa, non proprietà di selezione)

4

Vorrei invertire la mia selezione con AppleScript. Questo è analogo alla funzionalità di Adobe Photoshop (e di altri prodotti Adobe) "Inverti selezione (Ctrl / Cmd + I per deselezionare ciò che era precedentemente selezionato e seleziona ciò che non è stato selezionato)"

  1. I possibile selezionare un gruppo di celle con AppleScript.
  2. I possibile ottenere l'intervallo selezionato con AppleScript
  3. I possibile eseguire il ciclo di celle selezionate
  4. Mi piacerebbe selezionare tutte le celle che non sono attualmente selezionate

Codice

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

Celle originariamente selezionate

Selezionedesiderata

(tuttelecellenelfogliosonoselezionatechenoneranooriginariamenteselezionate)

    
posta Jonathan Komar 23.01.2017 - 21:24
fonte

2 risposte

2

Finalmente, ho una soluzione. Enorme grazie a Monomeeth per la versione VBA che mi ha messo sulla strada giusta. (E rendendo possibile farlo anche sotto Windows)

Funziona in modo simile alla versione di Monomeeth. Ha un intervallo considerato per motivi di prestazioni. Impostalo modificando di conseguenza questa linea:

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

Ecco qui:

-- 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
    
risposta data 23.02.2017 - 08:05
fonte
1

Ho lavorato a questa domanda per un po 'e, colpendo un muro di mattoni, ho deciso di provare a farlo funzionare usando Visual Basic. La mia speranza è che fare questo renderà più semplice ottenere il codice direttamente all'interno di AppleScript, quindi sto condividendo il codice Visual Basic nel caso in cui aiuti qualcun altro a far funzionare una versione di AppleScript - non che abbia rinunciato a questo ancora! :)

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

NOTE:

  • Mi sono imbattuto in un problema, ovvero che non sono riuscito a trovare un modo per farlo applicare all'intero foglio senza che causasse l'arresto di Excel per periodi di tempo estremamente lunghi (probabilmente perché deve controllare 1.048.576 righe e 16.384 colonne) per farlo.
  • Per aggirare questo problema ho usato Set s2 = Range("A1:Z100") per limitare l'area del foglio a cui si applica il codice all'intervallo di A1: Z100. Tuttavia, questo può essere modificato per adattarsi a un'area più ampia, se necessario.
  • Immagino che provare a coprire l'intero foglio sia un problema anche all'interno di AppleScript.
risposta data 16.02.2017 - 06:29
fonte

Leggi altre domande sui tag