Desidero creare una stringa delimitata da virgole nell'intervallo A1:A400
.Creazione di una stringa delimitata da virgola
Qual è il modo migliore per farlo? Dovrei usare un ciclo For
?
Desidero creare una stringa delimitata da virgole nell'intervallo A1:A400
.Creazione di una stringa delimitata da virgola
Qual è il modo migliore per farlo? Dovrei usare un ciclo For
?
Il modo più pigra è
s = join(Application.WorksheetFunction.Transpose([a1:a400]), ",")
Questo funziona perché .Value
proprietà di una gamma multicella restituisce un array 2D, e Join
aspetta serie 1D, e Transpose
sta cercando di essere troppo utile, così quando rileva un 2D array con una sola colonna, lo converte in un array 1D.
Nella produzione si consiglia di utilizzare almeno un po 'meno opzione pigrizia,
s = join(Application.WorksheetFunction.Transpose(Worksheets(someIndex).Range("A1:A400").Value), ",")
altrimenti sarà sempre utilizzato il foglio attivo.
Questa è una spiegazione splendidamente concisa di tre comportamenti piuttosto confusi che ho sempre compreso a metà. Ora sono a circa tre quarti. –
+1, chiarito qualcosa anche per me. –
@GSerg Come potrei creare la stessa stringa per l'intervallo da A1 a Z1? – user793468
È possibile utilizzare la funzione StringConcat creata da Chip Pearson. Si prega di consultare il link sottostante :)
Topic: concatenazione di stringhe
link: http://www.cpearson.com/Excel/StringConcatenation.aspx
Citazione Dal link nel caso in cui il link muore mai
questa pagina descrive una funzione VBA che è possibile utilizzare per concatenare i valori stringa in una formula matrice.
Lo StringConcat funzione
Al fine di superare queste carenze della funzione CONCATENA, è necessario costruire la nostra funzione scritta in VBA che affronterà i problemi della CONCATENA. Il resto di questa pagina descrive una funzione chiamata StringConcat. Questa funzione supera tutte le carenze di CONCATENATE. Può essere utilizzato per concatenare singoli valori di stringa, i valori uno o più intervalli di fogli di lavoro, matrici letterali e i risultati di un'operazione di formula di matrice.
La dichiarazione di funzione di StringConcat è la seguente:
Funzione StringConcat (settembre come stringa, ParamArray Args()) come stringa
Il parametro settembre è un personaggio o dei personaggi che separano le stringhe di essere concatenati. Questo può essere 0 o più caratteri. È richiesto il parametro Sep. Se non si desidera alcun separatore nella stringa del risultato, utilizzare una stringa vuota per il valore di Sep. Il valore Sep viene visualizzato tra ogni stringa concatenata, ma non appare né all'inizio né alla fine della stringa del risultato. Il parametro ParamArray Args è un valore di serie da concatenare. Ciascun elemento nel ParamArray può essere uno dei seguenti:
Una stringa letterale, ad esempio "A" Un intervallo di celle, specificato per indirizzo o per nome intervallo. Quando gli elementi di un intervallo bidimensionale sono concatenati, l'ordine di concatenazione è su una riga e poi giù sulla riga successiva. Un array letterale.Ad esempio, { "A", "B", "C"} o { "A", "B", "C"}
La funzione
Function StringConcat(Sep As String, ParamArray Args()) As Variant
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' StringConcat
' By Chip Pearson, [email protected], www.cpearson.com
' www.cpearson.com/Excel/stringconcatenation.aspx
' This function concatenates all the elements in the Args array,
' delimited by the Sep character, into a single string. This function
' can be used in an array formula. There is a VBA imposed limit that
' a string in a passed in array (e.g., calling this function from
' an array formula in a worksheet cell) must be less than 256 characters.
' See the comments at STRING TOO LONG HANDLING for details.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim S As String
Dim N As Long
Dim M As Long
Dim R As Range
Dim NumDims As Long
Dim LB As Long
Dim IsArrayAlloc As Boolean
'''''''''''''''''''''''''''''''''''''''''''
' If no parameters were passed in, return
' vbNullString.
'''''''''''''''''''''''''''''''''''''''''''
If UBound(Args) - LBound(Args) + 1 = 0 Then
StringConcat = vbNullString
Exit Function
End If
For N = LBound(Args) To UBound(Args)
''''''''''''''''''''''''''''''''''''''''''''''''
' Loop through the Args
''''''''''''''''''''''''''''''''''''''''''''''''
If IsObject(Args(N)) = True Then
'''''''''''''''''''''''''''''''''''''
' OBJECT
' If we have an object, ensure it
' it a Range. The Range object
' is the only type of object we'll
' work with. Anything else causes
' a #VALUE error.
''''''''''''''''''''''''''''''''''''
If TypeOf Args(N) Is Excel.Range Then
'''''''''''''''''''''''''''''''''''''''''
' If it is a Range, loop through the
' cells and create append the elements
' to the string S.
'''''''''''''''''''''''''''''''''''''''''
For Each R In Args(N).Cells
If Len(R.Text) > 0 Then
S = S & R.Text & Sep
End If
Next R
Else
'''''''''''''''''''''''''''''''''
' Unsupported object type. Return
' a #VALUE error.
'''''''''''''''''''''''''''''''''
StringConcat = CVErr(xlErrValue)
Exit Function
End If
ElseIf IsArray(Args(N)) = True Then
'''''''''''''''''''''''''''''''''''''
' ARRAY
' If Args(N) is an array, ensure it
' is an allocated array.
'''''''''''''''''''''''''''''''''''''
IsArrayAlloc = (Not IsError(LBound(Args(N))) And _
(LBound(Args(N)) <= UBound(Args(N))))
If IsArrayAlloc = True Then
''''''''''''''''''''''''''''''''''''
' The array is allocated. Determine
' the number of dimensions of the
' array.
'''''''''''''''''''''''''''''''''''''
NumDims = 1
On Error Resume Next
Err.Clear
NumDims = 1
Do Until Err.Number <> 0
LB = LBound(Args(N), NumDims)
If Err.Number = 0 Then
NumDims = NumDims + 1
Else
NumDims = NumDims - 1
End If
Loop
On Error GoTo 0
Err.Clear
''''''''''''''''''''''''''''''''''
' The array must have either
' one or two dimensions. Greater
' that two caues a #VALUE error.
''''''''''''''''''''''''''''''''''
If NumDims > 2 Then
StringConcat = CVErr(xlErrValue)
Exit Function
End If
If NumDims = 1 Then
For M = LBound(Args(N)) To UBound(Args(N))
If Args(N)(M) <> vbNullString Then
S = S & Args(N)(M) & Sep
End If
Next M
Else
''''''''''''''''''''''''''''''''''''''''''''''''
' STRING TOO LONG HANDLING
' Here, the error handler must be set to either
' On Error GoTo ContinueLoop
' or
' On Error GoTo ErrH
' If you use ErrH, then any error, including
' a string too long error, will cause the function
' to return #VALUE and quit. If you use ContinueLoop,
' the problematic value is ignored and not included
' in the result, and the result is the concatenation
' of all non-error values in the input. This code is
' used in the case that an input string is longer than
' 255 characters.
''''''''''''''''''''''''''''''''''''''''''''''''
On Error GoTo ContinueLoop
'On Error GoTo ErrH
Err.Clear
For M = LBound(Args(N), 1) To UBound(Args(N), 1)
If Args(N)(M, 1) <> vbNullString Then
S = S & Args(N)(M, 1) & Sep
End If
Next M
Err.Clear
M = LBound(Args(N), 2)
If Err.Number = 0 Then
For M = LBound(Args(N), 2) To UBound(Args(N), 2)
If Args(N)(M, 2) <> vbNullString Then
S = S & Args(N)(M, 2) & Sep
End If
Next M
End If
On Error GoTo ErrH:
End If
Else
If Args(N) <> vbNullString Then
S = S & Args(N) & Sep
End If
End If
Else
On Error Resume Next
If Args(N) <> vbNullString Then
S = S & Args(N) & Sep
End If
On Error GoTo 0
End If
ContinueLoop:
Next N
'''''''''''''''''''''''''''''
' Remove the trailing Sep
'''''''''''''''''''''''''''''
If Len(Sep) > 0 Then
If Len(S) > 0 Then
S = Left(S, Len(S) - Len(Sep))
End If
End If
StringConcat = S
'''''''''''''''''''''''''''''
' Success. Get out.
'''''''''''''''''''''''''''''
Exit Function
ErrH:
'''''''''''''''''''''''''''''
' Error. Return #VALUE
'''''''''''''''''''''''''''''
StringConcat = CVErr(xlErrValue)
End Function
Sono riluttante a criticare qualsiasi codice scritto da Chip Pearson - lui è un maestro riconosciuto dell'arte di sviluppo VBA ed Excel - ma questo non è il modo in cui si esegue la concatenazione di stringhe in VBA. Le tecniche di base sono evitare allocazioni e concatenazioni (ecco perché: http://www.aivosto.com/vbtips/stringopt2.html#huge) - Io uso join, split e replace per questo - e le tecniche più avanzate sono elencate in parti I, II e II di questo articolo web: http://www.aivosto.com/vbtips/stringopt3.html –
Inoltre ... Quella funzione Concatenato è vincolata dalle familiari limitazioni sulla lettura dei dati da celle contenenti più di 255 caratteri . Guarda il codice di esempio qui sotto, con una funzione "Join" 2-Dimensional. –
vorrei considerare @ GSerg di rispondi come risposta definitiva alla tua domanda.
Per completezza - e di affrontare alcune limitazioni in altre risposte - vorrei suggerire che si utilizza una funzione 'Join' in grado di supportare gli array 2-dimensionali:
s = Join2d(Worksheets(someIndex).Range("A1:A400").Value)
Il punto qui è che il La proprietà Value di un intervallo (purché non sia una singola cella) è sempre una matrice bidimensionale.
Si noti che il delimitatore di riga nella funzione Join2d
di seguito è presente solo quando ci sono Righe (plurale) da delimitare: non lo si vedrà nella stringa concatenata da un intervallo di una riga.
Join2d: A 2-Dimensional funzione Registrato in VBA ottimizzate stringhe movimentazione
note di codifica:
Join
non soffre di limitazione 255-char che colpisce la maggior parte (se non tutto) delle funzioni concatenate native in Excel e l'esempio di codice Range.Value sopra passerà nei dati, per intero, da celle contenenti stringhe più lunghe.Public Function Join2d(ByRef InputArray As Variant, _ Optional RowDelimiter As String = vbCr, _ Optional FieldDelimiter = vbTab,_ Optional SkipBlankRows As Boolean = False) As String' Join up a 2-dimensional array into a string. Works like VBA.Strings.Join, for a 2-dimensional array. ' Note that the default delimiters are those inserted into the string returned by ADODB.Recordset.GetString On Error Resume Next ' Coding note: we're not doing any string-handling in VBA.Strings - allocating, deallocating and (especially!) concatenating are SLOW. ' We're using the VBA Join & Split functions ONLY. The VBA Join, Split, & Replace functions are linked directly to fast (by VBA standards) ' functions in the native Windows code. Feel free to optimise further by declaring and using the Kernel string functions if you want to. ' **** THIS CODE IS IN THE PUBLIC DOMAIN **** Nigel Heffernan Excellerando.Blogspot.com Dim i As Long Dim j As Long Dim i_lBound As Long Dim i_uBound As Long Dim j_lBound As Long Dim j_uBound As Long Dim arrTemp1() As String Dim arrTemp2() As String Dim strBlankRow As String i_lBound = LBound(InputArray, 1) i_uBound = UBound(InputArray, 1) j_lBound = LBound(InputArray, 2) j_uBound = UBound(InputArray, 2) ReDim arrTemp1(i_lBound To i_uBound) ReDim arrTemp2(j_lBound To j_uBound) For i = i_lBound To i_uBound For j = j_lBound To j_uBound arrTemp2(j) = InputArray(i, j) Next j arrTemp1(i) = Join(arrTemp2, FieldDelimiter) Next i If SkipBlankRows Then If Len(FieldDelimiter) = 1 Then strBlankRow = String(j_uBound - j_lBound, FieldDelimiter) Else For j = j_lBound To j_uBound strBlankRow = strBlankRow & FieldDelimiter Next j End If Join2d = Replace(Join(arrTemp1, RowDelimiter), strBlankRow & RowDelimiter, "") i = Len(strBlankRow & RowDelimiter) If Left(Join2d, i) = strBlankRow & RowDelimiter Then Mid$(Join2d, 1, i) = "" End If Else Join2d = Join(arrTemp1, RowDelimiter) End If Erase arrTemp1 End Function
Per completezza, ecco il corrispondente 2-D funzione Split:
Split2d: Una funzione Split 2-Dimensional in VBA con ottimizzato stringa movimentazione
Public Function Split2d(ByRef strInput As String, _ Optional RowDelimiter As String = vbCr, _ Optional FieldDelimiter = vbTab, _ Optional CoerceLowerBound As Long = 0) As Variant ' Split up a string into a 2-dimensional array. Works like VBA.Strings.Split, for a 2-dimensional array. ' Check your lower bounds on return: never assume that any array in VBA is zero-based, even if you've set Option Base 0 ' If in doubt, coerce the lower bounds to 0 or 1 by setting CoerceLowerBound ' Note that the default delimiters are those inserted into the string returned by ADODB.Recordset.GetString On Error Resume Next ' Coding note: we're not doing any string-handling in VBA.Strings - allocating, deallocating and (especially!) concatenating are SLOW. ' We're using the VBA Join & Split functions ONLY. The VBA Join, Split, & Replace functions are linked directly to fast (by VBA standards) ' functions in the native Windows code. Feel free to optimise further by declaring and using the Kernel string functions if you want to. ' **** THIS CODE IS IN THE PUBLIC DOMAIN **** Nigel Heffernan Excellerando.Blogspot.com Dim i As Long Dim j As Long Dim i_n As Long Dim j_n As Long Dim i_lBound As Long Dim i_uBound As Long Dim j_lBound As Long Dim j_uBound As Long Dim arrTemp1 As Variant Dim arrTemp2 As Variant arrTemp1 = Split(strInput, RowDelimiter) i_lBound = LBound(arrTemp1) i_uBound = UBound(arrTemp1) If VBA.LenB(arrTemp1(i_uBound)) <= 0 Then ' clip out empty last row: common artifact data loaded from files with a terminating row delimiter i_uBound = i_uBound - 1 End If i = i_lBound arrTemp2 = Split(arrTemp1(i), FieldDelimiter) j_lBound = LBound(arrTemp2) j_uBound = UBound(arrTemp2) If VBA.LenB(arrTemp2(j_uBound)) <= 0 Then ' ! potential error: first row with an empty last field... j_uBound = j_uBound - 1 End If i_n = CoerceLowerBound - i_lBound j_n = CoerceLowerBound - j_lBound ReDim arrData(i_lBound + i_n To i_uBound + i_n, j_lBound + j_n To j_uBound + j_n) ' As we've got the first row already... populate it here, and start the main loop from lbound+1 For j = j_lBound To j_uBound arrData(i_lBound + i_n, j + j_n) = arrTemp2(j) Next j For i = i_lBound + 1 To i_uBound Step 1 arrTemp2 = Split(arrTemp1(i), FieldDelimiter) For j = j_lBound To j_uBound Step 1 arrData(i + i_n, j + j_n) = arrTemp2(j) Next j Erase arrTemp2 Next i Erase arrTemp1 Application.StatusBar = False Split2d = arrData End Function
Condividere e godere ... E attenzione per le interruzioni indesiderate riga nel codice, inseriti dal browser (o con funzioni di formattazione utile di StackOverflow)
+1 Great post! Perfino si intrufola in un 'Mid $' a sinistra e un 'LenB'! L'unico suggerimento nitpick molto minore è 'VbNullstring' piuttosto che' "" '.... Quindi vedo che sei Nigel H che pubblica occasionalmente sul Dicks Blog. Mi piace il tuo lavoro – brettdj
... hai aggiunto tutti gli spazi bianchi del codice. – brettdj
Sono io o è impossibile copiare e incollare correttamente nell'editor di vb? Ok [revision3 works] (https://stackoverflow.com/revisions/12054533/3) per copia e incolla – Vijay
È possibile utilizzare la funzione StringConcat creato da Chip Pearson. Si prega di consultare il link sottostante :) ** Argomento: String Concatenazione ** ** Link **: [http://www.cpearson.com/Excel/StringConcatenation.aspx](http://www.cpearson.com/Excel /StringConcatenation.aspx) –