问题
First, let me say that I hope that it is proper SO etiquette to be asking this in the same post as my original. It's all in the same vein, but I'm not sure this is proper. So, please, if I'm not right, correct me so I can fix it.
I created a macro to perform a TextToColumns a while back. I edited and cleaned up the macro. It was working just fine until I started propagating data into those fields using formulas instead of manually copying data into them, which was what I used to do.
Now, I've expanded on my worksheet's module code and realized that the method I wrote months ago interferes with formulas that now copy the values into the fields that I originally was performing the TextToColumns.
In short, is there a way to tell .TextToColumns to take the values of the range in which it's working and ignore the formula?
Sheet4.Range(categorySrcColumn & srcCategoryColLastRow)
.TextToColumns _
Destination:=Range(categoryDestColumn), _
Other:=True, _
OtherChar:="/", _
FieldInfo:=Array(1,1), _
TrailingMinusNumbers:=true
I checked the documentation for TextToColumns searching for xlValues but couldn't find anything like that.
---------- addendum -----------
Rachel. I appreciate your input. Perhaps you could assist a little bit more. I've plugged in your suggestion, but it simply is doing nothing. I've taken a few libterties here in hopes to combine what you've given with what I need. Disclaimer: I am by no means a VBA developer. What I know is what I've learned from google. I live in the Unix/Linux world so this is a very different bird to what I'm used to.
Here's what I have so far...
Public Function sbTextToColumn(srcRange As String, dstRange As String)
Dim vData As Variant
vData = Split(ActiveSheet.Range(srcRange).Value, "/")
' I need to massage the data in the srcRange a bit before I can separate it out.
' This is a partial sanity check on the data as well.
Range(srcRange).Replace What:="I/R", Replacement:="IR", Lookat:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False _
ReplaceFormat:=False
Range(srcRange).Replace What:="N/A", Replacement:="NA", Lookat:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False _
ReplaceFormat:=False
Range(srcRange).Replace What:=" ", Replacement:="", Lookat:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False _
ReplaceFormat:=False
ActiveSheet.Range(dstRange).Resize(ColumnSize:=UBound(vData) + 1) = vData
sbTextToColumn = ""
End Function
I cannot post an example of the spreadsheet, unfortunately. It's on a closed, secure network.
Now, when I plug this in in the worksheet via: =sbTextToColumn(C836, E836)
, nothing happens.
This is my first attempt at ever creating and using a UDF. Here's how I'm calling the function. I have a worksheet with the first three columns A-C grabbing data from another spreadsheet. Those columns are of course formulas. Column D is not used, but I'm placing the call to the UDF in here, hoping that that will work. Columns E-I are reserved for the T2C data and column J is used by pulling the same data as column B (yes, redundant, I know). My goal is that I'd like to get rid of column J (it's used for a vlookup in another worksheet and I may not be able to remove it but I'd like to). Ideally, I'd like to pull the source data from the other spreadsheet, sanity check it, split it out, and simply place the sorted data in the n columns necessary.
So, am I on the right track? I'm still working on this. If I make any progress, I'll post the progress. TIA!
回答1:
Functions, including UDFs, can only return a value to their caller. They cannot modify other cells.
Here is Rachel's method wrapped as a UDF:
Function sbTextToColumn(rng As Range) As Variant
Dim vData As Variant
vData = Split(rng.Value2, "/")
ReDim Preserve vData(0 To Application.Caller.Columns.Count - 1)
sbTextToColumn = vData
End Function
You enter it as a array function. In your example, say for row 2
- Select range
E2:I1
- Type
=sbTextToColumn(C2)
- Press Ctrl+Shift+Enter
- Copy the 5 cell range down for as many rows as needed
Functions not being able to modify other cells means you cannot do the sanitising in the UDF.
From your sample code you want to
- Replace I/R with IR, and N/A with NA
- Remove spaces
- Do this after the data is split out into columns
E:I
(so I/R will already be split into two cells) - Replace the original Column C formulas with sanitised data as values
Is this right?
If so, you would be best to not used a UDF at all, but rather use a Sub
(called from a quick key, or added to a menu)
Somthing like:
Sub sbTextToColumn()
Dim ws As Worksheet
Dim srcRng As Range
Dim rw As Range
Dim vData As Variant
Dim srcData As Variant
Dim dstData As Variant
Dim i As Long, j As Long
Dim maxCol As Long
Set ws = ActiveSheet
Set srcRng = Range(ws.Columns(3).Cells(1, 1), _
ws.Columns(3).Cells(ws.Columns(3).Rows.Count).End(xlUp))
srcData = srcRng
ReDim dstData(LBound(srcData, 1) To UBound(srcData, 1), 1 To 5)
For i = LBound(srcData, 1) To UBound(srcData, 1)
If srcData(i, 1) <> "" Then
' Split data
vData = Split(srcData(i, 1), "/")
maxCol = UBound(vData, 1)
If maxCol > 5 Then maxCol = 5
For j = 1 To maxCol + 1
dstData(i, j) = vData(j - 1)
Next
' Sanitise data
srcData(i, 1) = Replace(srcData(i, 1), "I/R", "IR", Compare:=vbTextCompare)
srcData(i, 1) = Replace(srcData(i, 1), "N/A", "NA", Compare:=vbTextCompare)
srcData(i, 1) = Replace(srcData(i, 1), " ", "", Compare:=vbTextCompare)
End If
Next
' Put results back in sheet
srcRng = srcData
srcRng.Offset(0, 2).Resize(, 5) = dstData
End Sub
If you actually want to sanitise before the split, simply swap the order of the Split data and Sanitise Data code blocks.
回答2:
This approach might work for you as it utilizes the Value property and is unaffected by formulas. It uses the Split function to split the data into a one-dimensional array. That array is then pasted into the cells to the right:
Sub sbTextToColumn()
Dim vData As Variant
vData = Split(Sheet4.Range("A1").Value, "/")
Sheet4.Range("B1").Resize(ColumnSize:=UBound(vData) + 1) = vData
End Sub
来源:https://stackoverflow.com/questions/8597830/excel-texttocolumns-method-in-vba-to-ignore-formulas