This question already has answers here:
Excel VBA, getting range from an inactive sheet
(3 answers)
Closed 3 years ago.
I'm trying to create a new chart with the following code:
Sheet1.Range("C1:C21").TextToColumns Destination:=Sheet1.Range("C1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
:=Array(1, 1), TrailingMinusNumbers:=True
Sheet1.Select
Set classificacio = Sheet1.Shapes.AddChart2(Style:=-1, XlChartType:=xlBarStacked, Left:=Sheet1.Cells(1, 1).Left, Top:=Sheet1.Cells(1, 1).Top, Width:=Sheet1.Range(Cells(1, 1), Cells(15, 8)).Width, Height:=Sheet1.Range(Cells(1, 1), Cells(20, 8)).Height, NewLayout:=True).Chart
classificacio.SetSourceData Source:=Range(Sheet1.Cells(11, 2), Sheet1.Cells(20, 3))
classificacio.HasTitle = False
It works. However, it doesn't work when I delete Sheet1.Select because the code starts when Sheet3 is active. It seems that Set classificacio = Sheet1.Shapes... only makes sense when Sheet1 is the ActiveSheet.
How could I create this chart avoiding the selection of Sheet1, where the chart is created, and keeping always Sheet3 as the ActiveSheet?
You are getting that error because the Cells object are not fully qualified. If you do not qualify them, then they will refer to the active sheet.
Change Sheet1.Range(Cells(1, 1), Cells(15, 8)) to Sheet1.Range(Sheet1.Cells(1, 1), Sheet1.Cells(15, 8)). Same with Sheet1.Range(Cells(1, 1), Cells(20, 8))
Or better still, Put then in a With-End With Block (Untested).
With Sheet1
.Range("C1:C21").TextToColumns Destination:=.Range("C1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
:=Array(1, 1), TrailingMinusNumbers:=True
Set classificacio = .Shapes.AddChart2(Style:=-1, XlChartType:=xlBarStacked, _
Left:=.Cells(1, 1).Left, _
Top:=.Cells(1, 1).Top, _
Width:=.Range(.Cells(1, 1), .Cells(15, 8)).Width, _
Height:=.Range(.Cells(1, 1), .Cells(20, 8)).Height, _
NewLayout:=True).Chart
classificacio.SetSourceData Source:=Range(.Cells(11, 2), .Cells(20, 3))
classificacio.HasTitle = False
End With
Related
I want to paste the columns of this text file in my workbook.
USAF-WBAN_ID STATION NAME COUNTRY STATE LATITUDE LONGITUDE ELEVATION
------------ ------------------------------ -------------------------------------------------- ------------------------------ -------- --------- ---------
404200 99999 AL AHSA SAUDI ARABIA +25.285 +049.485 +0179.2
I want to pull 7 variables (7 columns)
USAF-WBAN_ID; STATION NAME; COUNTRY; STATE; LATITUDE; LONGITUDE; ELEVATION
Below is what I've tried in several variations, and results are not reliable.
Sub A1_StationID()
Dim vFile As Variant
Dim wbCopyTo As Workbook
Dim wsCopyTo As Worksheet
Dim wbCopyFrom As Workbook
Dim wsCopyFrom As Worksheet
Set wbCopyTo = ActiveWorkbook
Set wsCopyTo = ActiveSheet
MsgBox "Please select weather stn.txt document"
Dim vFileName
vFileName = Application.GetOpenFilename("Text Files (*.txt), *.txt")
Application.ScreenUpdating = False
Workbooks.OpenText Filename:=vFileName, _
Origin:=xlMSDOS, StartRow:=1, DataType:=xlFixedWidth, _
FieldInfo:=Array(Array(0, 1), Array(13, 1), Array(44, 1), _
Array(127, 1), Array(136, 1), Array(147, 1), Array(154, 1)), _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=False, Comma:=False, Space:=False, _
Other:=False, TrailingMinusNumbers:=True
Set wbCopyFrom = Workbooks.Open(vFileName)
End Sub
Some of the output I get:
If I add a breakpoint on the second to last line of code, I get closer to the output I desire (with messed up columns).
First off - fantastic job posting working code and usable example data.
You were missing the array/field info designation for state and your final 3 columns were ~1/2 characters off. I removed the delimiter options as they don't matter if you're using xlFixedWidth.
Change
Workbooks.OpenText Filename:=vFileName, _
Origin:=xlMSDOS, StartRow:=1, DataType:=xlFixedWidth, _
FieldInfo:=Array(Array(0, 1), Array(13, 1), Array(44, 1), _
Array(127, 1), Array(136, 1), Array(147, 1), Array(154, 1)), _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=False, Comma:=False, Space:=False, _
Other:=False, TrailingMinusNumbers:=True
to
Workbooks.OpenText Filename:=vFileName, _
Origin:=xlMSDOS, StartRow:=1, DataType:=xlFixedWidth, _
FieldInfo:=Array(Array(0, 1), Array(13, 1), Array(44, 1), _
Array(95, 1), Array(126, 1), Array(135, 1), Array(144, 1), Array(154, 1)), _
TextQualifier:=xlDoubleQuote, TrailingMinusNumbers:=True
As a side-note Excel has a bad tendency to remember Text to Columns settings so if you were messing with those earlier, make sure they are set to standard settings.
my task is:
1) Select all cells in A row which contain values (done).
2) Text to Columns - example value 2017.01.01
Sub selectAndToColumns()
Dim LR As Long
LR = Range("A" & Rows.Count).End(xlUp).Row
Range("A1:A" & LR).SpecialCells(xlCellTypeConstants, 23).Select
'2nd step
Selection.TextToColumns Destination:=Range(A1), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=True, OtherChar _
:=".", FieldInfo:=Array(Array(1, 2), Array(2, 1), Array(3, 1))
End Sub
1 step is ok, but how can I use my selection instead of Range(A1) in 2nd step? Can I make a variable and how?
I'm not too sure about your requirements, but this will perform the TextToColumns without selecting anything (You can still change the destination to wherever you want the resulting data to be placed, you can do this by specifying a range or even using a variable where your range is stored):
Sub selectAndToColumns()
Dim LR As Long
LR = Range("A" & Rows.Count).End(xlUp).Row
Range("A1:A" & LR).SpecialCells(xlCellTypeConstants, 23).TextToColumns Destination:=Range("A1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=True, OtherChar _
:=".", FieldInfo:=Array(Array(1, 2), Array(2, 1), Array(3, 1))
End Sub
UPDATE
If you want to replace your destination with a variable instead of Range("A1") then something like below will work:
Sub selectAndToColumns()
Dim DestinationRange As String
Dim LR As Long
LR = Range("A" & Rows.Count).End(xlUp).Row
DestinationRange = "D1"
MsgBox DestinationRange
Range("A1:A" & LR).SpecialCells(xlCellTypeConstants, 23).TextToColumns Destination:=Range(DestinationRange), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=True, OtherChar _
:=".", FieldInfo:=Array(Array(1, 2), Array(2, 1), Array(3, 1))
End Sub
I'm not sure if I have understood your question properly, but if you just want to select Column A and paste it as values, I would use:
Columns("A:A").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Is there anyway to combine the following code to include the required columns in order for them to text to column or do I need to leave it as is? I have multiple ranges including U2, V2, N2, X2, AB2, & Z2
Set sh = Worksheets("Data")
With sh
Set rng = .[U2]
Set rng = .Range(rng, .Cells(.Rows.Count, rng.Column).End(xlUp))
rng.TextToColumns Destination:=rng, DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=False, Comma:=True, Space:=False, Other:=False, _
FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1)), TrailingMinusNumbers:=True
Set rng = .[V2]
Set rng = .Range(rng, .Cells(.Rows.Count, rng.Column).End(xlUp))
rng.TextToColumns Destination:=rng, DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=False, Comma:=True, Space:=False, Other:=False, _
FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1)), TrailingMinusNumbers:=True
Set rng = .[N2]
Set rng = .Range(rng, .Cells(.Rows.Count, rng.Column).End(xlUp))
rng.TextToColumns Destination:=rng, DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=False, Comma:=True, Space:=False, Other:=False, _
FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1)), TrailingMinusNumbers:=True
Set rng = .[X2]
Set rng = .Range(rng, .Cells(.Rows.Count, rng.Column).End(xlUp))
rng.TextToColumns Destination:=rng, DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=False, Comma:=True, Space:=False, Other:=False, _
FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1)), TrailingMinusNumbers:=True
Set rng = .[AB2]
Set rng = .Range(rng, .Cells(.Rows.Count, rng.Column).End(xlUp))
rng.TextToColumns Destination:=rng, DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=False, Comma:=True, Space:=False, Other:=False, _
FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1)), TrailingMinusNumbers:=True
Set rng = .[Z2]
Set rng = .Range(rng, .Cells(.Rows.Count, rng.Column).End(xlUp))
rng.TextToColumns Destination:=rng, DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=False, Comma:=True, Space:=False, Other:=False, _
FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1)), TrailingMinusNumbers:=True
End With
You can combine several ranges like this:
Set rng1 = Range("U2:U2")
Set rng2 = Range("V2:V2")
'and so on..
Set yourBigNewRange = Union(rng1, rng2, ... )
You can work with this new range exactly the same way you would work with any other range.
I am facing issue after copy and paste from export file from SAP it ask to convert to number option which is like error without converting to number formulas do not work. also cell value is number only.
I tried to make macro but it works on single column only. how to make it work on multiple column together and make it faster also as it stuck exel for long time.
code for converting to number
Columns("A:A").Select
Selection.TextToColumns Destination:=Range("A1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
:=Array(1, 1), TrailingMinusNumbers:=True
Columns("F:F").Select
Selection.TextToColumns Destination:=Range("F1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
:=Array(1, 1), TrailingMinusNumbers:=True
Columns("G:G").Select
Selection.TextToColumns Destination:=Range("G1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
:=Array(1, 1), TrailingMinusNumbers:=True
How shorter code and combine for multiple columns in single line.
Use an xlFixedWidth in your Range.TextToColumns method.
Dim c As Long, vCOLs As Variant
vCOLs = Array(1, 6, 7) 'columns A, F and G
With Worksheets("Sheet1")
For c = LBound(vCOLs) To UBound(vCOLs)
With .Column(c)
.TextToColumns Destination:=.Cells(1), DataType:=xlFixedWidth, _
FieldInfo:=Array(0, 1), TrailingMinusNumbers:=True
End With
Next c
End With
The variant array allow you to quickly specify the columns to be processed. Even with a large (~250K) number of rows, this should be fairly quick to cycle through.
I have this code to split strings. Currently if the counter is equal to the number of rows on which data is present, it will run properly. However, this number of rows is variable. How do I make the for loop run for as long there is data?
Sub SplitToColumns()
Range("A1").Select
For Counter = 0 To 100 Step 1
Selection.TextToColumns Destination:=ActiveCell, DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, _
Tab:=False, Semicolon:=False, Comma:=True, Space:=False, _
Other:=False, _
FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1)), _
TrailingMinusNumbers:=True
ActiveCell.Offset(1, 0).Select
Next Counter
End Sub
Something like this:
get the row number of the last populated row in column A. (Replace with the column of your choice). Then use that row number in the for-loop, but start with 1, not with zero. Remove the debug.print if no longer required.
Sub SplitToColumns()
Dim rowCount As Long
rowCount = Cells(rows.Count, "A").End(xlUp).Row
Debug.Print rowCount
Range("A1").Select
For Counter = 1 To rowCount Step 1
Selection.TextToColumns Destination:=ActiveCell, DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, _
Tab:=False, Semicolon:=False, Comma:=True, Space:=False, _
Other:=False, _
FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1)), _
TrailingMinusNumbers:=True
ActiveCell.Offset(1, 0).Select
Next Counter
End Sub
There are several other ways to make this code more efficient. For example, you don't need to select the cell before you do a TextToColumns. In fact, you can do a TextToColumns on a range of cells, you don't need to loop through all the cells in the range.
Use the technique above to get the row number of the last row, and then build a range starting in A1 and extending to column A, last populated row number.
Then perform a TextToColumns on the whole range, all in one go. Much, much faster than looping!!!
Sub SplitToColumns()
Dim rowCount As Long
Dim ws As Worksheet
'~~> Change this to the relevant sheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
rowCount = .Cells(.Rows.Count, "A").End(xlUp).Row
.Range("A1:A" & rowCount).TextToColumns _
Destination:=.Range("A1"), _
DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, _
ConsecutiveDelimiter:=False, _
Tab:=False, _
Semicolon:=False, _
Comma:=True, _
Space:=False, _
Other:=False, _
FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1)), _
TrailingMinusNumbers:=True
End With
End Sub