[vba] Creare una funzione che accetti un numero indefinito di parametri

Per questo esercizio vediamo come creare una funzione personalizzata simile (perché non andremo ad implementare tutte le alternative) al SOMMA.PIÙ.SE in VBA per Excel.

Anzitutto individuiamo le criticità:

  1. Avremo bisogno di accettare un range per la somma ed n coppie di parametri come intervalli e criteri, la nostra funzione avrà quindi la forma di FUNZIONE(somma, [intervallo 1], [criterio 1], …)
  2. I criteri possono essere numerici oppure stringhe di confronto, come per esempio “>2”

Anzitutto vediamo come creare una funzione che accetti n parametri come abbiamo definito di sopra. Per cui digitiamo in VBA:

In questo caso abbiamo inserito il minimo indispensabile, definendo il risultato come un Double, dichiarando internamente una variabile totale ed impostandola su 0. Questa variabile la utilizzeremo in seguito. L’argomento somma è di tipo Range (qui occhio agli indici, come vedremo tra poco!) e poi segue un vettore di parametri args definiti come Variant.

Per scorrere i vari parametri possiamo usare l’istruzione:

A questo punto vogliamo costruire un vettore di criteri lungo quanto l’intervallo della somma e che per ogni chiave contenga un valore equivalente a 0 oppure ad 1, in funzione che si debba o meno sommare il valore nell’intervallo somma.

Per fare questo definiamo:

Con il metodo somma.count misuriamo la dimensione del Range somma, attenzione perché il range si muove da 1 fino a somma.count, mentre il nostro vettore criteri andrà da 0 fino a somma.count – 1

Infine impostiamo tutto il vettore criteri() su 1, questo ci servirà tra poco per le operazioni logiche.

A questo punto non ci rimane che valutare tutti i criteri, tenendo presente che vanno a coppie di intervallo criteri e criterio. Perciò utilizzeremo l’istruzione:

Gli intervalli dei criteri si trovano in posizioni pari, mentre il criterio in posizione dispari.

Infine utilizzeremo il metodo Evaluate sfruttando la funzione SE di Excel per valutare ogni criterio, nel modo seguente:

Faccio notare che in Evaluate va scritta la funzione col nome in inglese. Dal momento che i criteri possono essere numerici oppure stringhe, come abbiamo detto all’inizio, dobbiamo distinguere tra le due cose e quindi scriveremo:

Infine ricordiamoci che tutti i criteri devono essere validi, quindi per modificare ogni posizione del vettore criteri() useremo il prodotto. In questo modo se sono tutti veri risulterà 1, un prodotto di tutti 1 insomma, mentre se anche un solo criterio sarà falso allora il prodotto risulterà 0, dal momento che basta uno 0 nel prodotto per azzerare tutto.

Detto tutto ciò la nostra funzione finale sarà simile a questa:

Inutile dire che la funzione potrebbe essere ulteriormente affinata per coprire tutti i possibili casi in cui può essere utilizzata SOMMA.PIÙ.SE 😉

Vedi articolo

[VBA] Aggiungere nuovo foglio con data corrente in Excel

Immaginiamo di voler aggiungere, in modo programmatico, un nuovo foglio con un nome e la data corrente, per esempio IMPORTAZIONE 10 09 2018.

Quello che vedremmo come risultato nella cartella di lavoro in Excel sarebbe qualcosa di analogo:

Per farlo costruiamo una funzione in VBA nel modo seguente:

Testiamo la funzione mettendola dentro una sub:

Come è possibile notare la funzione restituisce il riferimento al nuovo foglio creato, che possiamo utilizzare nella sub di esempio per scrivere, per esempio, dentro ad una cella.

Se volessimo aggiungere un controllo, nella solita funzione CreaNuovoFoglio, perché non ci siano fogli duplicati, sarebbe sufficiente modificare la funzione nella maniera seguente:

In questo modo al nome del foglio viene posposto un termine n-simo, in questo caso (1), (2) ecc. Se lo si desidera chiaramente si può aggiungere qualunque termine oppure decidere di interrompere l’operazione.

Vedi articolo

[windows] Programmare spegnimento automatico ad una determinata ora

Obiettivo: Programmare lo spegnimento automatico del computer ad una determinata ora, per esempio alle ore 20 tutti i giorni.

All’interno di Windows è possibile configurare delle attività programmate. Per farlo clicchiamo col destro sul tasto Start e selezioniamo Gestione computer.

Spostiamo su Utilità di pianificazione e poi tra le opzioni a destra scegliamo Crea attività di base.

Seguiamo la procedura guidata e diamo un nome alla nostra pianificazione, per esempio “Spegnimento automatico ore 20”

Scegliamo quando attivare l’attività, per esempio Ogni giorno.

A questo punto ci verrà chiesta la data e l’ora, nonché il numero di ricorrenze.

Scegliamo avvio programma dalla schermata successiva.

A questo punto selezioniamo il programma shutdown.exe e passiamogli il parametro -s

Il parametro -s avvierà lo spegnimento entro 60 secondi dall’esecuzione, altrimenti possiamo impostare lo spegnimento ad un tempo prefissato con il parametro -t, per esempio -t 30 per avviare lo spegnimento entro 30 secondi, o -t 0 per avviarlo immediatamente.

Premiamo avanti e poi fine.

 

Vedi articolo

[windows] Migrare utenti su un nuovo dominio, senza migrazione del dominio

Per quelli a cui piace complicarsi la vita, ecco come migrare i computer e gli utenti da un dominio all’altro, preservando configurazioni e file.

Scenario: abbiamo dei computer con degli utenti di dominio, con Windows Server, che vogliamo spostare su un nuovo dominio, senza però effettuare la migrazione del dominio stesso

Anzitutto assicuriamoci di avere sui computer l’utente amministratore locale accessibile. Qualora non ci fosse, o non se ne ricordasse la password, possiamo ripristinarlo seguendo questa guida.

Qualora l’utente administrator non fosse abilitato, ricordiamoci che possiamo attivarlo (eventualmente anche dalla modalità di ripristino) digitando:

A questo punto sul nostro computer avremo un utente di dominio, che chiameremo CONTOSO\Mario, e un utente locale Administrator.

  1. Attacchiamo il computer alla rete con il nuovo dominio, chiamato NEWCONTOSO, dove abbiamo creato un nuovo utente NEWCONTOSO\Mario
  2. Entriamo come amministratore locale
  3. Apriamo C:\Users ed individuiamo la cartella che apparteneva all’utente CONTOSO\Mario, supponiamo che sia mario.contoso
  4. Apriamo Esegui (WIN + R) e digitiamo regedit per aprire l’editor del registro
  5. Raggiungiamo l’elenco dei profili su HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\
  6. Qui compariranno varie voci del tipo S-1-5-21-XXXX dei profili degli utenti, cerchiamo le voci corrispondenti alla cartella mario.contoso alla voce ProfileImagePath
  7. Cancelliamo la voce del registro associata al profilo utente del precedente dominio
  8. Per evitare ogni forma di conflitto rinominiamo la cartella C:\Users\mario.contoso in qualcosa tipo C:\Users\mario.contoso__
  9. Scarichiamo CCleaner e facciamo una pulizia del registro
  10. Apriamo il Panello di controllo e creiamo un nuovo utente amministratore del computer, chiamato Mario, come l’utente che intendiamo registrare
  11. Andiamo sopra C:\Users\mario.contoso__ e clicchiamo col destro, andiamo su Proprietà > Sicurezza > Avanzate, qui andiamo su Autorizzazioni > Cambia autorizzazioni, se non esiste aggiungiamo il nuovo utente amministratore Mario e diamogli completa autorizzazione sulla cartella, spuntiamo anche le voci Includi autorizzazioni ereditarietà dell’oggetto padre di questo oggetto e Sostituisci tutte le autorizzazioni degli oggetti figlio con autorizzazioni ereditabili derivate da questo oggetto, premiamo OK e attendiamo. Se ci fossero degli errori ignoriamoli e diamo Continua fino alla fine. Poi andiamo su Proprietario > Modifica, se non vediamo l’utente Mario aggiungiamolo premendo Altri utenti o gruppi… altrimenti selezioniamolo e spuntiamo Sostituisci proprietario in sottocontenitori ed oggetti
  12. Adesso facciamo logout dall’account amministratore ed entriamo con l’utente amministratore locale Mario
  13. A questo punto apriamo il prompt dei comandi (WIN+R e poi cmd) e digitiamo il comando:

    In questo modo prendiamo il controllo della cartella
  14. Sistemiamo i permessi in modo che il nostro utente locale Mario abbia accesso completo
  15. Adesso usciamo da Mario (mi raccomando disconnettiamo l’utente) e torniamo su Administrator
  16. Una volta dentro andiamo su Esplora risorse e selezioniamo la visualizzazione dei file nascosti
  17. Adesso tagliamo (CTRL+X) le cartelle AppData, Documents, Pictures, Videos, Desktop (ed eventuali altre) dalla cartella C:\Users\mario.contoso__ e spostiamoli nella cartella dell’utente Mario locale, probabilmente C:\Users\mario
  18. Diamo OK a tutti gli alert, tentiamo Riprova laddove possibile, altrimenti diamo Ignora
  19. Riavviamo il computer
  20. A questo punto possiamo procedere a configurare il nuovo dominio, utilizzando il Computer Connector di Windows Server
  21. Una volta eseguita la connessione ci chiederà quali utenti vogliamo far migrare i profili, selezioniamo la seconda voce Configura il computer per me e per altri utenti
  22. Selezioniamo l’utente NEWCONTOSO\Mario e andiamo avanti
  23. Nella scelta del profilo selezioniamo il profilo locale Mario
  24. Proseguiamo e concludiamo la configurazione con le altre opzioni a nostra scelta
Vedi articolo

[windows] Ripristinare password di account locale su Windows 7/8

Problema: Ripristinare la password di un account locale, per esempio Administrator oppure un altro account, su un computer con Windows 7 oppure Windows 8

Questo esempio vale anche per Windows 8 (non ho ancora provato su Windows 10), mentre mi avvarrò di un Windows 7 per illustrare la procedura. Anzitutto procuriamoci un disco di installazione di Windows 7, con il quale poter avviare il ripristino del computer. Nel caso non si disponga di tale disco lo si può anche scaricare online, per esempio da qualche torrent, perché quello che ci interessa non è installare un nuovo sistema operativo, ma solo ripristinare quello corrente, quindi non è indispensabile disporre di una copia originale o di codici di licenza.

In secondo luogo assicuriamoci che sia possibile avviare il disco dal BIOS, tipicamente cambiando l’ordine di boot dalla configurazione del BIOS (nella maggior parte dei PC si accede al BIOS premendo F2 oppure CANC/DEL) oppure accedendo al menu di boot (tipicamente premendo F12 all’avvio).

Una volta inserito il disco premiamo INVIO per accedere al disco, anziché avviare il sistema operativo:

A questo punto sarà avviato il sistema di ripristino, selezioniamo la lingua:

Premiamo avanti, a questo punto selezioniamo dalla voce in basso l’opzione per il ripristino del computer.

Verranno cercati i sistemi operativi ripristinabili. Selezioniamo a questo punto il sistema operativo che ci interessa (tipicamente ce ne sarà uno solo) e procediamo:

Premiamo avanti. A questo punto si apriranno le opzioni di ripristino:

Clicchiamo su Prompt dei comandi

A questo punto notiamo che ci troviamo nell’unità X:, il sistema operativo è stato probabilmente montato sull’unità D: (attenzione! tipicamente non si tratta di C:, anche se sul computer originale Windows era montato su C:). Per visualizzare tutte le unità montate basta digitare:

Ci verrà mostrato qualcosa di simile a questo:

Possiamo entrare in D: digitando semplicemente D: e premendo INVIO. Utilizzando il comando dir possiamo accertarci di essere nel volume giusto.

A questo punto vogliamo sostituire Sticky Keys con il Prompt dei comandi sul nostro PC originale. Sticky Keys si avvia premendo ripetutamente il tasto SHIFT, in questo modo senza dover accedere al PC avvieremo il prompt dei comandi. Per maggiori informazioni su Sticky Keys suggerisco la pagina di Wikipedia.

Per fare la sostituzione digitiamo sul prompt dei comandi:

In questo modo faremo una copia di backup del file sethc.exe nella radice del sistema e poi lo sostituiremo con cmd.exe.

Il risultato dovrebbe apparire così se tutto è andato bene:

Usciamo dal prompt dei comandi digitando exit, dopodiché premiamo il tasto riavvio.

Una volta riavviato il sistema premiamo per 5 volte rapidamente il tasti SHIFT finché non compare il prompt, di fronte alla schermata di login.

Adesso digitiamo:

In questo modo verranno visualizzati gli account registrati sul PC.

Nel mio caso sono disponibili gli utenti Administrator, Guest, Mario e SVEN. Immaginiamo di voler cambiare la password per l’utente Mario. Quindi digitiamo:

Al posto di USERNAME e PASSWORD digitiamo il nome utente e la nuova password.

Nel mio caso ho digitato Mario e come password Pappapero4321.

Se tutto è andato bene possiamo accedere con il nostro utente e la nuova password.

A questo punto è importante ripristinare sethc.exe per motivi di sicurezza. Se si prova a farlo dal sistema operativo avviato si otterrà un errore.

Per fare il ripristino è necessario ripetere i primi passaggi e accedere al sistema di ripristino. A quel punto digitiamo:

Così ripristineremo la copia che abbiamo salvato sulla radice nella posizione originale.

Vedi articolo

[windows] Copiare cartelle e file preservando i permessi e le condivisioni sulla destinazione

Problema: Copiare dati e cartelle di un profilo, come per esempio AppData, su un altro profilo senza copiare anche i relativi permessi e preservando i permessi e le condivisioni del profilo di destinazione

Senza entrare nel merito del perché si potrebbe voler fare qualcosa del genere (molto utile in realtà quando si fa la migrazione dei profili) è sufficiente utilizzare robocopy.

Nello specifico il seguente comando:

/E serve a copiare tutto il contenuto, comprese le sottocartelle vuote

/R:0 serve per saltare eventuali errori, dovuti magari a mancanza di permessi

Potremmo aggiungere anche il /COPY:flag[s] per copiare solo determinate caratteristiche (di predefinito è su /COPY:DAT, D=Data, A=Attributi, T=Timestamps, eventualmente S=Informazioni di sicurezza dei NFTS ACLs, O=Informazioni sul proprietario, U=Auditing info)

Vedi articolo

[steam] Steam o il gioco non si apre senza riavviare il PC

Problema: dopo aver giocato e chiuso il gioco o Steam, quando si cerca di rilanciare un gioco o Steam stesso, nessuno dei due parte, finché non si riavvia il computer

Questo problema è cominciato ad apparire di recente, senza motivo apparente, ed anzi per un po’ ho pensato che potesse essere collegato in qualche modo a Final Fantasy XV, che avevo installato da poco (ma poi ho scoperto non essere il colpevole). Leggendo in giro ho trovato svariate soluzioni, tra le quali si suggeriva addirittura di disinstallare e reinstallare Steam, e riavviare il PC è comunque una bella seccatura, specialmente se si vuole giocare senza dover chiudere per forza tutti i programmi che si avevano aperti.

La soluzione che per me ha funzionato è la seguente (testata su Windows 10):

  1. Aprire il task manager ed individuare anzitutto ogni eventuale processo di Steam attivo (per aprirlo premere WIN+R e digitare taskmgr, oppure CTRL+ALT+CANC e poi selezionare Gestione Attività)
  2. Individuare un eventuale programma ancora aperto e chiuderlo, cliccandoci sopra col destro e selezionando Termina attività (in generale a me capita dopo che lo riduco ad icona e non sembra ci sia un programma attivo di Steam, ma solo il processo)
  3. A questo punto individuare il servizio Steam Client Service, cliccare col destro e spostarsi sui dettagli
  4. Nei dettagli dovremmo vedere una serie di processi come nell’esempio seguente, cliccare col destro su ciascuno di loro e scegliere Termina Albero Processi (questo è molto importante per chiudere tutte le istanze di Steam, potreste anche notare che Steam.exe non può essere terminato, dando errore di “Accesso negato“, non ve ne preoccupate)
  5. Fatto questo andiamo su Servizi ed individuiamo Steam Client Service, clicchiamoci sopra col destro e scegliamo Riavvia (oppure Avvia, a seconda dei casi)

A questo punto dovrebbe essere possibile far partire nuovamente Steam ed ogni eventuale gioco che si voglia giocare.

E adesso torniamo a divertirci su Eos
Vedi articolo

[excel] Copiare solo celle visibili e non quelle nascoste

Problema: Quando si seleziona un gruppo di celle e si copiano normalmente, vengono copiate anche le celle nascoste, mentre si vorrebbero copiare solamente le celle visibili

Immaginiamo di avere un intervallo di celle come il seguente:

Se adesso decidessimo di nascondere la terza riga avremmo il seguente risultato:

Selezionando l’intervallo A1:B5 e copiando (per esempio con CTRL+C) copieremo in realtà anche la riga 3 che è nascosta. Lo stesso vale quando si utilizzano i filtri sulle celle.

Per copiare invece solamente le celle visibili dobbiamo fare nel modo seguente:

  1. Selezioniamo l’intervallo che vogliamo copiare come faremmo normalmente
  2. Nella scheda Home spostiamoci su Trova e seleziona e selezioniamo Vai a formato speciale…
  3. Nella finestra selezioniamo Solo celle visibili e premiamo Ok
  4. Eseguiamo la copia come faremmo normalmente (o banalmente premendo CTRL+C)

Adesso abbiamo copiato solo le celle visibili e possiamo incollarle dove vogliamo.

Per maggiori approfondimenti consiglio la guida ufficiale di Office: Copiare solo le celle visibili

Vedi articolo

[windows server] Spostare la cartella dei file di aggiornamento di WSUS

Obiettivo: spostare la cartella di archiviazione degli aggiornamenti di WSUS in una nuova posizione

Tipicamente i file di aggiornamento gestiti dal server WSUS si trovano nella posizione C:\Comsys WSUS.

Per cambiare tale cartella è sufficiente trovare il programma wsusutil.exe ed effettuare lo spostamento nel modo in cui segue:

  1. WIN+R per aprire ESEGUI e digitare CMD per aprire il prompt dei comandi
  2. Spostarsi nella cartella di wsusutil.exe tipicamente dovrebbe trovarsi in C:\Program Files\Update Services\Tools
  3. Digitare quindi CD C:\Program Files\Update Services\Tools
  4. Creare quindi la nuova cartella di destinazione dei file di aggiornamento, per esempio su un disco F creando una cartella F:\WSUS
  5. Digitare quindi wsusutil.exe movecontent F:\WSUS F:\move.log
  6. Questo comando avvierà lo spostamento dei file dalla posizione attuale a quella nuova
Vedi articolo

[c#] Creare una classe base generica con tipo aperto

Immaginiamo di voler creare in C# una classe generica che possa gestire dei tipi aperti, un po’ come succede per le liste. Per esercizio vogliamo creare una classe chiamata Materie che accetti diverse classi come tipo di materia gestito, per esempio una classe Matematica. L’oggetto che vogliamo creare sarà di questo tipo:

A questo punto vogliamo avere un metodo per aggiungere dei voti per gli studenti della data materia, nel modo seguente:

E infine vogliamo poter estrarre, dal nostro oggetto m, una media dei voti, passandogli una funzione che si occuperà di definire il meccanismo di estrazione del voto dall’oggetto generico sul tipo aperto.

Per cui creiamo anzitutto la classe Matematica:

E poi creiamo la classe Materie:

Faccio notare che il metodo getMediaVoti accetta come argomento un metodo generico che prenda che abbia come argomento il tipo aperto T e come restituzione un double (supponiamo che volendo calcolare dei voti essi dovranno essere comunque ricondotti a double).

Uniamo il tutto nel modo seguente:

In questo caso l’oggetto m si comporta in modo analogo ad una lista, permettendo l’aggiunta di n elementi del tipo T, nel nostro caso Matematica. Dal momento che noi non conosciamo i specifici parametri e metodi di T chiediamo, per calcolare la media, che ci venga passata una funzione a cui sarà delegata l’estrazione dei voti come double dall’oggetto aperto di tipo T, tale metodo è calcolaMedia che accetta come argomento un oggetto di tipo Matematica.

Vedi articolo