Problema limite massimo caratteri



  • Problema limite massimo caratteri
    di campa90 data: 02/12/2015 00:23:15

    Ciao a tutti,

    grazie al vostro aiuto una settimana fa sono riuscito a scrivere una semplice macro (qua sotto) per fargli fare un lavoro noioso:

    devo controllare su una stringa se è presenza una sequenza di lettere "XXX..." e se dopo 3 caratteri casuali è presente una seconda sequenza di lettere "YYY..."

    Se è vero il programma deve darmi in output la posizione di questo sovrapposizione, altrimenti continua a cercare fino a quando non finisce la stringa.

    Il programma funziona e non ci sono problemi sotto questo punto di vista, ma il vero problema che è emerso è che non posso inserire in input stringhe più lunghe di 100 (circa) caratteri.
    E io devo analizzare una stringa da 3 milioni di caratteri...

    Pensavo di usare sto programmino e sfruttando il limite massimo di caratteri string (circa 70000 se non ricordo male) di spezzarla una 60ina di volte, copiando-incollandola manualmente in pezzi da 50000 caratteri.
    Ma farlo per sequenze da 100 caratteri è inutile, ci metto più tempo che controllarlo a mano.

    Se qualcuno ha idee su come risolvere questo problema mi dica pure!

    P.S.: Ho provato a non usare InputBox e mettere il contenuto della variabile direttamente all'interno del codice, ma in ogni caso questo "limite massimo" rimane e mi chiude le " in automatico, escludendo il resto delle lettere della stringa.

    Grazie in anticipo!

     
    Sub prova()
    '
    ' prova Macro
    
    Dim stringa, target, target2 As String
    Dim npos, output, primapos, lunghezza As Long
    
    
    stringa = InputBox("inserire stringa")
    
    
    target = InputBox("inserire target")
    target2 = InputBox("inserire target2")
    
    npos = InStr(1, stringa, target)
    
    
    Do While npos > 0
    primapos = npos
    If primapos + 4 = InStr(npos + 3, stringa, target2) Then
    output = output & primapos & "; "
    End If
    npos = InStr(npos + 1, stringa, target)
    Loop
    
    MsgBox ("è stato trovato in posizione " & output)
    '
        Application.Goto Reference:="prova"
        
    End Sub
    



  • di Marius44 data: 02/12/2015 07:51:53

    Ciao campa90
    Leggo dalla Guida di VBA:
    - In una InputBox possono starci circa 1000 caratteri.
    - Il tipo di dati String può contenere oltre 2miliardi (se di lunghezza variabile ovvero circa la metà se di lunghezza fissa) di caratteri.

    Ti chiedo: ma che stringa è da 3milioni di caratteri? da dove la recuperi? e perchè inserirla in una InputBox?
    Visto il problema forse è meglio fornire qualche chiarimento in più.

    Ciao,
    Mario



  • di patel data: 02/12/2015 07:58:01

    io proverei ad utilizzare un file di testo in cui metti la stringa da analizzare, apri il file e leggi la stringa o le stringhe se ci sono dei separatori, sarebbe utile vedere un esempio (non di 3 milioni di caratteri)





  • di campa90 data: 03/12/2015 01:42:33

    Provo a spiegare un pò meglio quello che devo fare:

    sono un ricercatore in biologia molecolare, e sto cercando di usare excel come sistema per analizzare determinate sequenze di DNA.

    In parole povere, prendo un gene di interesse selezionando la sequenza di DNA +/-50000 nucleotidi dall'inizio del gene. La sequenza di DNA si trova facilmente da database su internet.
    In questo modo otterrò una sequenza di lettere/basi nucleotidiche (AAATTGGTTTCCC....) che contiene il gene stesso e certe regioni regolatorie del gene sparse lungo questi 100000 nucleotidi.

    Il problema è che le regioni regolatorie, raramente sono complete o ben definite e quindi io ne devo cercare delle nuove.

    Per fare ciò, volevo usare la funzione "cerca" per trovare nuove regioni regolatorie. Queste regioni hanno una sequenza specifica che si trova sparsa "random" nel DNA. Un esempio per questa sequenza potrebbe essere AAATTTGGnnnTTAAAG, dove le 3 n non sono caratteri fissi ma possono essere qualsiasi lettera.

    Quindi, una voltà ottenuta la stringa e la sequenza da cercare, voglio vedere quante volte e dove si venga a trovare la sequenza bersaglio. Questo è ciò che volevo fare.

    Avevo pensato ad inputbox perchè mi sembrava un ottimo modo per poter cambiare stringa o la sequenza bersaglio velocemente, ma essendo poco esperto di VBA sono incappato in questo limite.
    C'è un modo per aggirarlo?

    Più o meno dovrò fare questa ricerca, su una 30ina di geni diversi perciò dovrò controllare circa 3 milioni di lettere con questo metodo. Devo trovare il modo automatizzato che mi permetta di fare questo in ore, non giorni.

    Se riuscite a darmi una mano siete super!

    P.S.: ho già cercato di usare diversi programmi per analisi di sequenza di DNA (alcuni dei quali uso abitualmente), ma non riesco a fare una ricerca accurata come vorrei perchè certi parametri non sono modificabili e quindi i risultati sono inutili.



  • di Marius44 data: 03/12/2015 07:14:22

    Buongiorno campa90
    Non m'intendo di biologia ma vorrei darti una mano. Nell'esempio che hai riportato conosci a priori quali sono le "nnn"? conosci se si presentano in numero costante (per es, 3n, 2n, ecc.)? Se le risposte sono entrambe si, ci si può provare.
    Se, invece, sia la "natura" delle n (cioè una volta un separatore è una n, altra volta una s, ecc.), sia la distribuzione (una volta ogni 10, ogni 20, ecc.), sia la quantità (una volta sono 3, altra volta 2, altra volta 4) la vedo piuttosto dura.
    Potresti essere così gentile da postare un esempio di file (non con 3milioni di caratteri) con una sequenza e uno o più separatori? Grazie e ciao,
    Mario



  • di campa90 data: 03/12/2015 10:09:29

    Grazie per l'aiuto, provo a rispondere alla tua domanda.

    Le "n", in una sequenza di DNA possono essere qualsiasi lettera. Le 3 "n" tra le due sequenze servono a dare uno spazio fisico alla proteina per interagire (come se fosse una calamita con due braccia, ho provato a rappresentarla con un immagine)

    (non mi fa mettere link diretti) imageshack.com/a/img910/5557/StPt8f.png

    Quindi lo spazio tra le due sequenze è costante, perchè in questo caso le "braccia della calamita" sono distanziate da 3 nucleotidi (che possono avere qualsiasi sequenza).

    Con la frase sopra spero di aver risposto alla tua domanda sulla "natura" e sulla "quantità" delle n, ma non capisco cosa tu intenda con la distribuzione.

    in ogni caso scrivo un esempio:

    sequenza di DNA (stringa da 200 lettere):

    CAGATTTTAGGAACAGATTGTTCTAGCTCTCTGCATGACACTTTTTAGGGCTAACTACTTAAATCGCACAGTCAAAAACCATTTCTGAGACTACTTTAATTGTGAAAGACTCTCTTCCTCTTCTTCACTCAACCCCAGGAACAGCCTGTTCTTATGCAAACTAACATTTGCAAGCCAAGCTTTTTCTTATAAGCTTTTGG

    Prima sequenza/braccio

    GGAACA

    e di seguito, dopo 3 lettere casuali, deve esserci la seconda sequenza/braccio

    TGTTCT

    ho inserito nella stringa di DNA due volte la sequenza in cui questa ricerca è vera:

    la prima in posizione 10, mentre la seconda in posizione 138, quindi alla fine della ricerca excel dovrebbe dirmi queste due posizioni.

    Se non sono stato chiaro su qualche punto chiedete pure!



  • di ninai data: 03/12/2015 10:39:23

    ciao
    molto interessante.
    premettendo che vi sono i limiti di numero caratteri prima menzionati , con formule:
    in A1: stringa
    in A2: primo spezzone
    in A3: secondo spezzone
    A4: vuota
    in A5: =RICERCA($A$2&"*"&$A$3;$A$1;A4+1)
    trascini in basso

    con il VBA si può fare molto di meglio



  • di Albatros54 data: 03/12/2015 12:16:44

    Ho cercato di capire, il codice gira , ma non riesco a capire se risolve il tuo problema.
    Ho inserito delle inputbox, che prelevano le stringa da una cella , senza limitazione di lunghezza.Provalo
    Ciao
    Albatros54

       
     
    Sub prova()
    '
    ' prova Macro
    
    Dim stringa, target, target2 As String
    Dim npos, output, primapos, lunghezza As Long
    
    stringa = Application.InputBox("Selezionare ","SELEZIONA RANGE", , , , , , 2)
    target = Application.InputBox("Selezionare ", "SELEZIONA RANGE", , , , , , 2)
    target2 = Application.InputBox("Selezionare ", "SELEZIONA RANGE", , , , , , 2)
    
    npos = InStr(1, stringa, target)
    MsgBox "valore " & target & "trovato in posizione" & npos
    
    Do While npos > 0
    primapos = npos
    If primapos + 4 = InStr(npos + 3, stringa, target2) Then
    output = primapos
    End If
    npos = InStr(npos + 1, stringa, target)
    Loop
    
    MsgBox ("è stato trovato in posizione " & primapos)
    '
        Application.Goto Reference:="prova"
        
    End Sub
    






  • di Mister_x (utente non iscritto) data: 03/12/2015 13:08:58

    ciao

    attivando la proposta di ninai,Ciao
    ( con il VBA si può fare molto di meglio )

    una funzione da inserire in un modulo
    ammettendo come riferimento i dati proposti da Ninai
    utilizzo
    =cercapossec(A1;A2;A3) risultato 10 138

    prova con 4 volte la stessa stringa
    =cercapossec(CONCATENA(A1;A1;A1;A1);A2;A3) = 10 138 210 338 410 538 610 738

    ciao





     
    Option Explicit
    Public Function CercaPosSec(stringa As String, Sec1 As String, Sec2 As String) As String
    Dim Npos As Long
    Dim Nstr As String
    Npos = 0
    Nstr = ""
    Do While IsError(Application.Search(Sec1 & "*" & Sec2, stringa, Npos + 1)) = False
     Npos = Application.Search(Sec1 & "*" & Sec2, stringa, Npos + 1)
     Nstr = Nstr & Npos & " "
    Loop
    CercaPosSec = Nstr
    End Function
    






  • di scossa data: 03/12/2015 14:27:45

    Una proposta di UDF con le RegEx.

    sequenzaDNA(StringaDNA;preTag;postTag)

    Testata su una stringa di 4.000.000 di caratteri, trova le 40.000 posizioni, occhiometricamente, in meno di due o tre scondi.

    esempi d'uso:

    =sequenzaDNA(StringaDNA;"GGAACA";"TGTTCT")
    =sequenzaDNA(A1;A2;A3)



    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)

     
    Function SequenzaDNA(sDNA As String, sPre As String, sPost As String) As Variant
      'by scossa
    
      Dim oRE As Object
      Dim oMatchColl As Object
      Dim sPatt As String
      Dim nPos As Long
      Dim j As Long
      Dim vRet As Variant
     
      Set oRE = CreateObject("vbscript.regexp")
      With oRE
        .Global = True
        .IgnoreCase = True
        sPatt = "(" & sPre & ")(?:[A-Z]{3})(" & sPost & ")"
        .Pattern = sPatt
        If .test(sDNA) Then
          Set oMatchColl = .Execute(sDNA)
          With oMatchColl
            For j = 0 To .Count - 1
              vRet = vRet & oMatchColl(j).firstindex + 1 & " "
            Next
          End With
        Else
          vRet = 0
        End If
        SequenzaDNA = Replace(Trim(vRet), " ", ";")
      End With
    
      Set oRE = Nothing
      Set oMatchColl = Nothing
    
    End Function
    



  • di campa90 data: 03/12/2015 15:20:01

    Testato l'ultimo metodo di Scossa, e nonostante le mie limitate capacità su VBA sono riuscito a far funzionare tutto e l'ho testata su 200 mila lettere e funziona perfettamente ed è estremamente facile da modificare.

    Grazie a Scossa e a tutti gli per l'aiuto e per il supporto!

    Buona giornata!