Macro confronto celle

Anonimo
2014-04-16T08:14:29+00:00

Buongiorno a tutti,

avrei bisogno di supporto per lo sviluppo di una macro probabilmente abbastanza complesssa.

Semplicemente ho 2 collone:

  • colonna 1: statica (nomi)
  • colonna 2: dinamica (numeri)

Vorrei che la macro confrontasse i valori (Colonna 2) che hanno lo stesso nome (colonna 1) e che mi avvertisse (alert) nel caso in cui si verifichi una determinata condizione.

Ringrazio anticipatamente per eventuali risposte.

Un saluto

Daniel

Microsoft 365 e Office | Excel | Per la casa | Windows

Domanda bloccata. Questa domanda è stata eseguita dalla community del supporto tecnico Microsoft. È possibile votare se è utile, ma non è possibile aggiungere commenti o risposte o seguire la domanda.

0 commenti Nessun commento
Risposta accettata dall'autore della domanda
Anonimo
2014-04-29T10:30:53+00:00

intanto ti ringrazio nuovamente per l'aiuto e scusa se sono stato assente, causa lavoro.

Provando tutte le varie combinazioni, ho notato che il file effettivamente funziona correttamente inserendo "mioparametro" anche con numeri decimali, l'unico problema resta che excel va in crash se la colonna da confrontare (i prezzi) sono in formato percentuale.

Ciao Daniel,

In principio, l'uso dei prezzi in formato percentuale nondovrebbe avere alcuna influenza negativa in quanto le percentuali non sono altro che numeri, o interi o decimali.

Pertanto ho fatto un rapido test, semplicemente convertando il formato percentuale i miei valori di prova storici. Come risultato ho ricevuto la seguente e-mail:

I risulati di stamattina mostrati nel file allegato erano:

ITALIA Fiat 8,56 Eni 18,61 -10,05 29/04/2014 11.16.13
ITALIA Eni 18,61 Finmeccanica 6,42 12,19 29/04/2014 11.16.13
FRANCIA Carrefour 28,6 Peugeout 12,96 15,64 29/04/2014 11.16.13
GERMANIA Mercedes 17,25 Vw 28,75 -11,5 29/04/2014 11.16.13
GERMANIA Mercedes 17,25 Audi 6,95 10,3 29/04/2014 11.16.13
GERMANIA Mercedes 17,25 Polo 3,00 14,25 29/04/2014 11.16.13
GERMANIA Vw 28,75 Audi 6,95 21,8 29/04/2014 11.16.13
GERMANIA Vw 28,75 Polo 3,00 25,75 29/04/2014 11.16.13

Noterai che i risultati sono invariati rispetto a quelli della mia ultima risposta: in altre parole, come previsto, il cambio di formato in formato percentuale non ha avuto alcuna influenza sui risultati ottenuti.

Per utilmente portare avanti la questione, forse sarebbe possibile postare una copia di una ventina di righe, mostrando i dati problematici nelle colonne A, B e Q. Assicurarti che, dopo la riduzione a 20 valori percentuali, si continua a riscontrare il problema descritto e sostituire i titoli e altri dati sensibili.

===

Regards,

Norman

La risposta è stata utile?

0 commenti Nessun commento
Risposta accettata dall'autore della domanda
Anonimo
2014-04-27T11:10:32+00:00

Ciao Daniel,

Ciao Norman, ho gia fatto tutte le prove del caso, anche con numeri interi, qualsiasi valore diverso da zero manda excel in crash.

Ora ho sostituito la colonna prezzi manualmente con dei valori interi e tutto funziona correttamente, se invece inserisco numeri con la virgola va nuovamente in crash, credo sia questo il problema !

Io non credo che l'uso dei valori decimali per i valori originari abbia alcuna influenza.

Al questo riguardo, vorrei ricordarti che nei miei test ho usato i tuoi dati di esempio che comprendevano esclusivamente i numeri decimali. Se rivedi le mie risposte in questo thread, vedrai degli  esempi di 'screenshots' (catture schermo) dei miei risultati dei test, i quali comprendono numeri decimali.

Nonostante questo, ho effettuato numerosi test nel tentativo di riprodurre, anche parzialmente, la tua esperienza. Perché non avevo potuto reprodurre i tuoi problemi, ho deciso di modificare i settaggi del mio computer e mi sono spostato in Italia: ho convertito le mie impostazioni di lingua da Inglese a Italiano e più importante, ho convertito il separatore decimale dal punto inglese alla virgola italiana; ho anche fatto delle modifiche simili ai miei settaggi di tempo.

Anche con questi settagi, non ho potuto indurre un 'crash'. Infatti, con i settaggi italiani, e utilizzando i tuoi dati (decimali) di esempio, stamattina, ho ricevuto la seguente email di avviso:

Aprendo il file allegato (Alarm.xls), vedo al fondo i segenti dati:

Eni 18,61 Finmeccanica 6,42 12,19 27/04/2014 10.55.57
FRANCIA Carrefour 28,60 Peugeout 12,96 15,64 27/04/2014 10.55.57
GERMANIA Mercedes 17,25 Polo 3,00 14,25 27/04/2014 10.55.57
GERMANIA Vw 28,75 Audi 6,95 21,80 27/04/2014 10.55.57
GERMANIA Vw 28,75 Polo 3,00 25,75 27/04/2014 10.55.57

Ho provato la costante mioParametro con un valore di 10.125 (punto inglese). Nessun problema, nessun crash! Sempe cercando di replicare i tuoi problemi, ho anche provato con un mioParametro di "10,125" (virgola italiana, tra virgolette). Anche utilizzando una stringa 'italiana' anziché un valore numerico inglese, il codice ha fatto una conversione implicita per convertire il valore testo con virgola italiana in un valore numerico inglese e  quindi ha dato gli stessi risultati senza alcun problema. A questo punto dovrei spiegare che la costante mioParametro é dichiarata come tipo 'double' e pertanto un valore testo non dovrebbe essere valido.  

Prima di abbandonare i miei test, e come tentativo finale, ho provato a sostituire il valore della costante mioParemetro con "10.125", cioè un valore di testo, utilizzando il separatore decimale inglese. Questa volta, con il gestore di errori disabilitato, il codice è entrato in un ciclo infinito! Per essere preciso, non si tratta di un crash:  potevo finalmente entrare in modo 'debug', premendo ripetutamente il tasto Esc.

In sommario, pertanto, l'unico modo in cui ho potuto riprodurre dei problemi analoghi alla tua esperienza è stata di assegnare un valore di testo non valido alla costante mioParametro. Tuttavia, per questa assegnazione non valida di causare il problema segnalato, il valore del testo assegnato doveva utilizzare il separatore decimale inglese e il computer ha dovuto utilizzare le impostazioni italiani. Pertanto, assicurarti  che sia assegnato solo un valore numerico inglese (punto, senza virgolette). 

Oltre di queste osservazioni non riesco di spiegare perché tu   verifichi problemi, mentre il codice suggerito funziona senza alcun problema per me.

===

Regards,

Norman

La risposta è stata utile?

0 commenti Nessun commento

61 risposte aggiuntive

Ordina per: Più utili
  1. Anonimo
    2014-04-22T13:16:15+00:00

    Ciao Daniel,

    Ciao Norman, grazie davvero tante per il lavoro che hai fatto, ho provato a seguire le tue indicazioni ma ricevo un errore in questa stringa:

     .SaveAs Filename:=sCopyFileName, FileFormat:=OpenXMLWorkbook

    "errore di compilazione: variabile non definita"

    Mia colpa! A l'ultimo momento ho modificato il codice a volo! Questa riga dovrebbe essere

                .SaveAs Filename:=sCopyFileName, FileFormat:=51    '\ xlOpenXMLWorkbook

     [6]  Sostituito con il nome del foglio nel quale arrivano le quotazioni aggiornate, che vengono però pescate da un altro foglio aggiornato in DDE (forse qui il problema ? ).

    Non credo che abbia nulla da fare con il problema che hai incontrato. Tuttavia, questo fatto nuovo è di fondamentale importanza per il funzionamento del codice! Il codice che è stato postato nel modulo di codice del foglio di lavoro (aka Foglio1) risponde solo alle variazioni DDE o modifiche manuali e non ai risultati delle formule! Pertanto, questo codice Worksheet_Activate dovrebbe essere spostato nel foglio di lavoro che viene aggiornato in DDE.

    Detto questo, come suggerito nella mia rispoosta precedente, prova il codice 'a mano', avviando la routine MySpreads: Alt-F8 | MySpreads | Esegui

    Se c'è un problema con lo spostamento del codice al modulo di codice del foglio aggiornato in DDE, nel senso che il codice sarebbe eseguito in risposta ad estranei collegamenti DDE, posterò codice diagnostico che ci permetta di superare questo inconveniente.

    ===

    Regards,

    Norman

    La risposta è stata utile?

    0 commenti Nessun commento
  2. Anonimo
    2014-04-22T10:24:36+00:00

    Ciao Norman, grazie davvero tante per il lavoro che hai fatto, ho provato a seguire le tue indicazioni ma ricevo un errore in questa stringa:

     .SaveAs Filename:=sCopyFileName, FileFormat:=OpenXMLWorkbook

    "errore di compilazione: variabile non definita"

    i vari punti:

    [1] Sostituisci C2:C100 con l’intervallo di interesse.

    ******[2]**Sostituisci ****  il valore di 10con il valore voluto per li parametro del spread

    [3]  Sostituisci  il nome del foglio a scelta personale

    [4]  Sostituisci C:\MyAlarms\Alarm.xls  con un percorso e nome di file appropriato

    [5]  Sostituisci Pippo.xlsx con il nome del file di interesse

     [6]  Sostituisci Foglio1 con il nome del foglio che viene aggiornato tramite DDE

     [7]  Sostituisci topoDOTgiggioAToutlookDOTcom ****con un indirizzo di email valido.

    Sono stati definiti come:

    ******[1]******colonna delle quotazioni

    ******[2]******0.2

    [3]  invariato ("Report")

    [4]  invariato, ho creato cartella: C:\MyAlarms

    [5]  Sostituito con il nome del file excel

     [6]  Sostituito con il nome del foglio nel quale arrivano le quotazioni aggiornate, che vengono però pescate da un altro foglio aggiornato in DDE (forse qui il problema ? ).

     [7]  Sostituito con mia mail personale

    Un altro dettaglio, la colonna relativa all' ID è la C e la quotazione corrispondente L.

    Se il problema invece è il numero 6, procedo a modificare la struttura del file e ti aggiorno.

    Grazie ancora molte per la tua disponibilità.

    Un saluto

    Daniel

    La risposta è stata utile?

    0 commenti Nessun commento
  3. Anonimo
    2014-04-22T06:27:21+00:00

    Ciao Daniel,

    Prova qualcosa del genere:

    Fai clic dx sulla linguetta del foglio che viene aggiornato tramite DDE |  Visualizza Codice |

    e incolla il seguente codice nel modulo di codice del foglio:

    '===========>>

    Option Explicit

    '----------->>

    Private Sub WorksheetChange(ByVal Target As Range)

        Dim Rng As Range

        Const sIndirizzo_DDE As String = "C2:C1****00"                                     '<<==== Modifica**[1]**

        Set Rng = Me.Range(sIndirizzo_DDE)

        If Not Intersect(Rng, Target) Is Nothing Then

            Call MySpreads

        End If

    End Sub

    '<<===========

    Alt IM  per inserire un nuvo modulo di codice e nel modulo vuoto, incolla il seguente codice:

    '==========>>

    Option Explicit

    '---------->>

    Public Sub MySpreads()

        Dim WB As Workbook

        Dim SH As Worksheet, destSH As Worksheet

        Dim oDic As Object, oDic2 As Object

        Dim Rng As Range, destRng As Range

        Dim rCell As Range

        Dim arrParentKeys As Variant, arrParentItems As Variant

        Dim arrChildKeys As Variant, arrChildItems As Variant

        Dim arrHeaders As Variant, arrOut() As Variant

        Dim i As Long, j As Long, k As Long

        Dim p As Long, q As Long, r As Long

        Dim iLastRow As Long, jLastRow As Long

        Dim dDate As Date, dTime As Date

        Const sIntestazioni As String = _

              "ID,Titolo-1,Quote,Titolo-2,Quote,Spread,Data,Ora"

        Const mioParametro As Double = 10                                           '<<==== Modifica**[2]**

        Const sReportShName As String = "Report"                               '<<==== Modifica [3]

        Const sCopyFileName As String = "C:\MyAlarms\Alarm.xls"        '<<==== Modifica**[4]**

        On Error GoTo ErrHandler

        Application.ScreenUpdating = False

        dDate = Format(Date, "dd/mm/yy")

        dTime = Format(Time, "hh:mm:ss")

        Set WB = ThisWorkbook    'Workbooks("Pippo.xlsx")                '<<==== Modifica**[5]**

        With WB

            Set SH = .Sheets("Foglio1")                                                  '<<==== Modifica**[6]**

            On Error Resume Next

            Set destSH = .Sheets(sReportShName)

            If Err.Number = 9 Then

                arrHeaders = Split(sIntestazioni, ",")

                Set destSH = .Sheets.Add(after:=SH)

                With destSH

                    .Name = sReportShName

                    With .Range("A1").Resize(1, UBound(arrHeaders) + 1)

                        .Value = arrHeaders

                        With .Font

                            .Size = 12

                            .Bold = True

                            .Underline = True

                        End With

                    End With

                End With

            End If

            Err.Clear

        End With

        On Error GoTo ErrHandler

        With SH

            iLastRow = LastRow(SH, .Columns("A:A"))

            Set Rng = .Range("A2:C" & iLastRow)

        End With

        With destSH

            jLastRow = LastRow(destSH, .Columns("A:A"))

            Set destRng = .Range("A" & jLastRow + 1 - (jLastRow <> 1))

        End With

        Set oDic = CreateObject("Scripting.Dictionary")

        oDic.CompareMode = vbTextCompare

        For i = 1 To Rng.Rows.Count

            With Rng.Cells(i, 2)

                If oDic.Exists(.Value) Then

                    Set oDic2 = oDic.Item(.Value)

                    If Not oDic2.Exists(.Value) Then

                        oDic2.Add Key:=.Offset(0, -1), Item:=.Offset(0, 1)

                    End If

                Else

                    Set oDic2 = CreateObject("Scripting.Dictionary")

                    oDic2.CompareMode = vbTextCompare

                    oDic2.Add Key:=.Offset(0, -1), Item:=.Offset(0, 1)

                    oDic.Add Key:=.Value, Item:=oDic2

                End If

            End With

        Next i

        arrParentKeys = oDic.Keys

        For i = 0 To UBound(arrParentKeys)

            Set oDic2 = oDic.Item(arrParentKeys(i))

            arrChildKeys = oDic2.Keys

            arrChildItems = oDic2.Items

            k = oDic2.Count

            For j = 0 To k - 1

                For p = j + 1 To k - 1

                    If Abs(arrChildItems(j) - arrChildItems(p)) > mioParametro Then

                        q = q + 1

                        ReDim Preserve arrOut(1 To 8, 1 To q)

                        arrOut(1, q) = arrParentKeys(i)

                        arrOut(2, q) = arrChildKeys(j)

                        arrOut(3, q) = arrChildItems(j)

                        arrOut(4, q) = arrChildKeys(p)

                        arrOut(5, q) = arrChildItems(p)

                        arrOut(6, q) = arrChildItems(j) - arrChildItems(p)

                        arrOut(7, q) = dDate

                        arrOut(8, q) = dTime

                    End If

                Next p

            Next j

        Next i

        With destRng.Resize(q, UBound(arrOut, 1))

            .Value = Application.Transpose(arrOut)

            .EntireColumn.AutoFit

            For r = 1 To .Columns.Count Step 2

                With destSH.UsedRange

                    .Columns(r).Interior.ColorIndex = 9

                    .Columns(r + 1).Interior.ColorIndex = 6

                    .Columns(6).Font.ColorIndex = 3

                End With

            Next r

        End With

        destSH.Copy

        With Application

            .DisplayAlerts = False

            With ActiveWorkbook

                .SaveAs Filename:=sCopyFileName, FileFormat:=OpenXMLWorkbook

                .Close

            End With

            .DisplayAlerts = True

        End With

        Call InformaDaniel(q, dTime, dDate, sCopyFileName)

    XIT:

        Set oDic2 = Nothing

        Set oDic = Nothing

        Application.ScreenUpdating = True

        On Error GoTo 0

        Exit Sub

    ErrHandler:

        Call MsgBox(Prompt:="Error " _

                            & Err.Number _

                            & " (" _

                            & Err.Description _

                            & ") nella routine: Tester", _

                    Buttons:=vbCritical, _

                    Title:="ERRORE")

        Err.Clear

        Resume XIT

    End Sub

    '---------->>

    Public Sub InformaDaniel(AlarmNum As Long, _

                             AlarmTime As Date, _

                             AlarmDate As Date, _

                             AlarmFile As String)

        Dim oApp As Object

        Dim oMail As Object

        Dim sBody As String

        Set oApp = CreateObject("Outlook.Application")

        Set oMail = oApp.CreateItem(0)

        sBody = "Ciao Daniel," _

                & vbNewLine & vbNewLine _

                & "Alle " & AlarmTime & Space(1) _

                & Format(AlarmDate, "ddd dd/mm/yyyy") _

                & vbNewLine & _

                "Ci sono stato verificato " & AlarmNum _

                & " coppie di titoli" _

                & vbNewLine & _

                "in cui lo spread e' stato in eccesso del valore previsto" _

                & vbNewLine & _

                "Vedi il file allegato per i dettagli."

        On Error Resume Next

        With oMail

            .To = "topoDOTgiggioAToutlookDOTcom"                                  '<<==== Modifica**[7]**       

            .CC = ""

            .BCC = ""

            .Subject = "SPREAD WARNING!"

            .Body = sBody

            .Attachments.Add (AlarmFile)

            .Send

        End With

        On Error GoTo 0

        Set oMail = Nothing

        Set oApp = Nothing

    End Sub

    '---------->>

    Public Function LastRow(SH As Worksheet, _

                            Optional Rng As Range)

        If Rng Is Nothing Then

            Set Rng = SH.Cells

        End If

        On Error Resume Next

        LastRow = Rng.Find(What:="*", _

                           after:=Rng.Cells(1), _

                           Lookat:=xlPart, _

                           LookIn:=xlFormulas, _

                           SearchOrder:=xlByRows, _

                           SearchDirection:=xlPrevious, _

                           MatchCase:=False).Row

        On Error GoTo 0

    End Function

    '<<==========

    [1] Sostituisci C2:C100 con l’intervallo di interesse.

    ******[2]******Sostituisci ****  il valore di 10 **** con il valore voluto per li parametro del spread

    [3]  Sostituisci  il nome del foglio a scelta personale

    [4]  Sostituisci C:\MyAlarms\Alarm.xls  con un percorso e nome di file appropriato

    [5]  Sostituisci Pippo.xlsxcon il nome del file di interesse

     [6]  Sostituisci Foglio1con il nome del foglio che viene aggiornato tramite DDE

     [7]  Sostituisci topoDOTgiggioAToutlookDOTcom ****con un indirizzo di email valido.

    Alt-Q per chiudere l’editor di VBA e tornare a Excel.

    Per vedere il funzionamento del codice 'a mano',:

    Alt-F8 per aprire la finestrina macro

    Seleziona MySpreads | Esegui

    Il codice copi i suoi risultati nella forma di una tabella di 8 colonne sul foglio Report, lasciando una riga vuota sotto i dati precedenti. I dati avranno la seguente forma:

    ID Titolo-1 Quote Titolo-2 Quote Spread Data Ora
    ITALIA Fiat 8.56 Eni 18.61 -10.05 20/04/2014 21:44:51
    ITALIA Eni 18.61 Finmeccanica 6.42 12.19 20/04/2014 21:44:51
    FRANCIA Carrefour 28.6 Peugeout 12.96 15.64 20/04/2014 21:44:51
    GERMANIA Mercedes 17.25 Vw 28.75 -11.5 20/04/2014 21:44:51
    GERMANIA Mercedes 17.25 Audi 6.95 10.3 20/04/2014 21:44:51
    GERMANIA Mercedes 17.25 Polo 3 14.25 20/04/2014 21:44:51
    GERMANIA Vw 28.75 Audi 6.95 21.8 20/04/2014 21:44:51
    GERMANIA Vw 28.75 Polo 3 25.75 20/04/2014 21:44:51
    ITALIA Fiat 8.56 Eni 18.61 -10.05 20/04/2014 21:49:31
    ITALIA Eni 18.61 Finmeccanica 6.42 12.19 20/04/2014 21:49:31
    FRANCIA Carrefour 28.6 Peugeout 12.96 15.64 20/04/2014 21:49:31
    GERMANIA Mercedes 17.25 Vw 28.75 -11.5 20/04/2014 21:49:31
    GERMANIA Mercedes 17.25 Audi 6.95 10.3 20/04/2014 21:49:31
    GERMANIA Mercedes 17.25 Polo 3 14.25 20/04/2014 21:49:31
    GERMANIA Vw 28.75 Audi 6.95 21.8 20/04/2014 21:49:31
    GERMANIA Vw 28.75 Polo 3 25.75 20/04/2014 21:49:31

    Come vedrai, ho utilizzato i tuoi dati, aggiungendo un nuovo ID GERMANIA e i titoli dependenti Audi, vW, Polo e Mercedes; questo allo scopo di aumentare il numero di 'coppie'.

    Inoltre, il codice crea un nuovo workbook Alarms.xlsx con una copia dei dati del foglio Report; questo file viene salvato nella cartella C:\myAlarms. Per soddifare la tua esigenza di  "scattare allarmi (pop up o altro)", il codice ti invia una email con allegato una copia del file Alarms.xlsx.

    Infine, in utilizo 'normale', il codice di evento (WorkSheet_Change), nel modulo di codice del foglio che viene aggiornato tramite DDE (Foglio1), risponde ai cambiamenti dei valori di interesse (C2:C100) e avvia la procedura MySpreads con i risultati descritti.

    ===

    Regards,

    Norman

    La risposta è stata utile?

    0 commenti Nessun commento