Debugging a QueryTables.Add script - vba

Sub FindData()
Dim accountNumber As Range
Set accountNumber = Range(Range("A2"), Range("A2").End(xlDown))
Dim dataSet As QueryTable
For Each Value In accountNumber
Set dataSet = .QueryTables.Add( _
Connection:="URL;http://www.prad.org/CamaDisplay.aspx?OutputMode=Display&SearchType=RealEstate&ParcelID=" & Value, _
Destination:=ThisWorkbook.Worksheets(2).Range("A1"))
Next Value
With dataSet
.RefreshOnFileOpen = False
.WebFormatting = xlWebFormattingNone
.BackgroundQuery = True
.WebSelectionType = xlSpecifiedTables
.WebTables = "3"
End With
With Application
dataSet.Refresh BackgroundQuery:=False
End With
End Sub
The ultimate goal here is to pull data from the URL and drop it into Worksheet(2). The values in accountNumber go at the end of the URL for each page to draw data from.
This is my first VBA script, and right off the bat, it's giving me an error on Sub FindData()
I have the table of accountNumbers. The URL for one account is the given URL with an accountNumber after the final =. I am trying to iterate through one webpage per accountNumber and extract from each.

Set dataSet = ActiveSheet.QueryTables.Add( _
Connection:="URL;http://www.prad.org/CamaDisplay.aspx?OutputMode=Display&SearchType=RealEstate&ParcelID=" & Value, _
Destination:=ThisWorkbook.Worksheets(2).Range("A1"))
QueryTables needs to be properly referenced. You can use a sheet qualifier like :
Sheets("yourname").QueryTables or something.
You can remove the dot too...

Look into my code and see if this helps. I added a lot of comments to help you understand better the way the whole thing works.
Option Explicit
Sub FindData()
Const strURL As String = "URL;http://www.prad.org/CamaDisplay.aspx?OutputMode=Display&SearchType=RealEstate&ParcelID="
Dim shActive As Worksheet
Dim shDestination As Worksheet
Dim oQuery As QueryTable
Dim rAccounts As Range
Dim rAccount As Range
'Initialize the variables
Set shActive = ActiveSheet
' Note the "." in front of the ranges. That's how you use "With"
With shActive
Set rAccounts = .Range(.Range("A2"), .Range("A2").End(xlDown))
End With
' Remove any old query otherwise they will pile up and slow down
' your workbook
Call RemoveSheetQueries(shActive)
' Loop through the accounts and add the queries
For Each rAccount In rAccounts
Set oQuery = Nothing
Set oQuery = shActive.QueryTables.Add(Connection:=strURL & rAccount.Value, _
Destination:=shActive.Range("A1"))
' Set the properties of the new query and eventually run it.
With oQuery
.RefreshOnFileOpen = False
.WebFormatting = xlWebFormattingNone
.BackgroundQuery = True
.WebSelectionType = xlSpecifiedTables
.WebTables = "3"
' This last line will actually get the data
.Refresh BackgroundQuery:=False
End With
Next rAccount
End Sub
' Procedure to remove all old Queries
Sub RemoveSheetQueries(ByRef shToProcess As Worksheet)
Dim lTotal As Long
Dim i As Long
lTotal = shToProcess.QueryTables.Count
For i = lTotal To 1 Step -1
shToProcess.QueryTables(i).Delete
Next i
End Sub
I hope it helps :)

Related

Excel VBA - Copy table data from website and put into excel?

I am trying to copy a table from a website and put this into excel.
My table can be identified by the elementID "VisibleReportContentctl32".
For some reason, my code produces this error:
'object required'
on this line: Range("A1").Text = dat
Here's my full code:
Option Explicit
Public Sub GetSSRSData()
Dim IE As Object: Set IE = New InternetExplorerMedium
Dim TR_Elements As Object
Dim TR As Object ' Table Row
Dim TD_Elements As Object
Dim TD As Object ' Table Data
Dim RowNumb As Integer
Dim Columns As Integer
Dim ColumnNumb As Integer
Dim x As Integer
Dim dat As String
With IE
.Visible = True
.Navigate ("http://gbrlon02-sql-17/Reports/Pages/Report.aspx?ItemPath=%2fCutlass+Reports%2fManagement+Reporting%2fForwardOrdersSticksOnly+-+ForecastVariance+(Monthly+Report)")
Do While IE.Busy Or IE.ReadyState <> 4
DoEvents
Loop
If IsObject(.Document.getElementById("VisibleReportContentctl32_ctl09")) Then
dat = IE.Document.getElementById("VisibleReportContentctl32_ctl09").innerHTML
Range("A1").Text = dat
Else
MsgBox "doesn't"
End If
End With
End Sub
please can someone show me where I am going wrong?
Use [Power Query][Table from web] is simple and stable
That URL doesn't work for me. Your code should look something like this...
Option Explicit
Sub gethtmltable()
Dim objWeb As QueryTable
Dim sWebTable As String
'You have to count down the tables on the URL listed in your query
'This example shows how to retrieve the 2nd table from the web page.
sWebTable = 2
'Sets the url to run the query and the destination in the excel file
'You can change both to suit your needs
Set objWeb = ActiveSheet.QueryTables.Add( _
Connection:="URL;http://www.vbaexpress.com/kb/default.php", _
Destination:=Range("A1"))
With objWeb
.WebSelectionType = xlSpecifiedTables
.WebTables = sWebTable
.Refresh BackgroundQuery:=False
.SaveData = True
End With
Set objWeb = Nothing
End Sub
You just need to identify which specific table you want to import data from.

Run Time Error '1004': Paste Method Of worksheet Class Failed error

Copy pasting 1 line of text from word to excel using VBA.
When the code reaches the below line I am getting the below error.
ActiveSheet.Paste
Run Time Error '1004': Paste Method Of worksheet Class Failed error
But if I click Debug button and press F8 then it's pasting the data in excel without any error.
This error occurs each time the loop goes on and pressing debug and F8 pasting the data nicely.
I did several testing and unable to find the root cause of this issue.
Also used DoEvents before pasting the data code but nothing worked.
Any suggestions?
EDIT:-
I am posting the code since both of you are saying the same. Here is the code for your review.
Sub FindAndReplace()
Dim vFR As Variant, r As Range, i As Long, rSource As Range
Dim sCurrRep() As String, sGlobalRep As Variant, y As Long, x As Long
Dim NumCharsBefore As Long, NumCharsAfter As Long
Dim StrFind As String, StrReplace As String, CountNoOfReplaces As Variant
'------------------------------------------------
Dim oWord As Object
Const wdReplaceAll = 2
Set oWord = CreateObject("Word.Application")
'------------------------------------------------
Application.ScreenUpdating = False
vFR = ThisWorkbook.Sheets("Sheet1").Range("A1").CurrentRegion.Value
On Error Resume Next
Set rSource = Cells.SpecialCells(xlCellTypeConstants)
On Error GoTo 0
If Not rSource Is Nothing Then
For Each r In rSource.Cells
For i = 2 To UBound(vFR)
If Trim(vFR(i, 1)) <> "" Then
With oWord
.Documents.Add
DoEvents
r.Copy
.ActiveDocument.Content.Paste
NumCharsBefore = .ActiveDocument.Characters.Count
With .ActiveDocument.Content.Find
.ClearFormatting
.Font.Bold = False
.Replacement.ClearFormatting
.Execute FindText:=vFR(i, 1), ReplaceWith:=vFR(i, 2), Format:=True, Replace:=wdReplaceAll
End With
.Selection.Paragraphs(1).Range.Select
.Selection.Copy
r.Select
ActiveSheet.Paste'Error occurs in this line pressing debug and F8 is pasting the data
StrFind = vFR(i, 1): StrReplace = vFR(i, 2)
NumCharsAfter = .ActiveDocument.Characters.Count
CountNoOfReplaces = (NumCharsBefore - NumCharsAfter) / (Len(StrFind) - Len(StrReplace))
.ActiveDocument.UndoClear
.ActiveDocument.Close SaveChanges:=False
If CountNoOfReplaces Then
x = x + 1
ReDim Preserve sCurrRep(1 To 3, 1 To x)
sCurrRep(1, x) = vFR(i, 1)
sCurrRep(2, x) = vFR(i, 2)
sCurrRep(3, x) = CountNoOfReplaces
End If
CountNoOfReplaces = 0
End With
End If
Next i
Next r
End If
oWord.Quit
'Some more gode goes here... which is not needed since error occurs in the above loop
End Sub
If you want to know why I have chosen word for replacement then please go through the below link.
http://www.excelforum.com/excel-programming-vba-macros/1128898-vba-characters-function-fails-when-the-cell-content-exceeds-261-characters.html
Also used the code from the below link to get the number of replacements count.
http://word.mvps.org/faqs/macrosvba/GetNoOfReplacements.htm
Characters(start, length).Delete() method really seems not to work with longer strings in Excel :(. So a custom Delete() method could be written which will work with decoupled formating informations and texts. So the text of the cell can be modified without loosing the formating information. HTH.
Add new class named MyCharacter. It will contain information about text and
formating of one character:
Public Text As String
Public Index As Integer
Public Name As Variant
Public FontStyle As Variant
Public Size As Variant
Public Strikethrough As Variant
Public Superscript As Variant
Public Subscript As Variant
Public OutlineFont As Variant
Public Shadow As Variant
Public Underline As Variant
Public Color As Variant
Public TintAndShade As Variant
Public ThemeFont As Variant
Add next new class named MyCharcters and wrap the code of the new
Delete method in it. With Filter method a new collection of MyCharacter is created. This collection contains only the characters which should remain. Finally in method Rewrite the text is re-written from this collection back to target range along with formating info:
Private m_targetRange As Range
Private m_start As Integer
Private m_length As Integer
Private m_endPosition As Integer
Public Sub Delete(targetRange As Range, start As Integer, length As Integer)
Set m_targetRange = targetRange
m_start = start
m_length = length
m_endPosition = m_start + m_length - 1
Dim filterdChars As Collection
Set filterdChars = Filter
Rewrite filterdChars
End Sub
Private Function Filter() As Collection
Dim i As Integer
Dim newIndex As Integer
Dim newChar As MyCharacter
Set Filter = New Collection
newIndex = 1
For i = 1 To m_targetRange.Characters.Count
If i < m_start Or i > m_endPosition Then
Set newChar = New MyCharacter
With newChar
.Text = m_targetRange.Characters(i, 1).Text
.Index = newIndex
.Name = m_targetRange.Characters(i, 1).Font.Name
.FontStyle = m_targetRange.Characters(i, 1).Font.FontStyle
.Size = m_targetRange.Characters(i, 1).Font.Size
.Strikethrough = m_targetRange.Characters(i, 1).Font.Strikethrough
.Superscript = m_targetRange.Characters(i, 1).Font.Superscript
.Subscript = m_targetRange.Characters(i, 1).Font.Subscript
.OutlineFont = m_targetRange.Characters(i, 1).Font.OutlineFont
.Shadow = m_targetRange.Characters(i, 1).Font.Shadow
.Underline = m_targetRange.Characters(i, 1).Font.Underline
.Color = m_targetRange.Characters(i, 1).Font.Color
.TintAndShade = m_targetRange.Characters(i, 1).Font.TintAndShade
.ThemeFont = m_targetRange.Characters(i, 1).Font.ThemeFont
End With
Filter.Add newChar, CStr(newIndex)
newIndex = newIndex + 1
End If
Next i
End Function
Private Sub Rewrite(chars As Collection)
m_targetRange.Value = ""
Dim i As Integer
For i = 1 To chars.Count
If IsEmpty(m_targetRange.Value) Then
m_targetRange.Value = chars(i).Text
Else
m_targetRange.Value = m_targetRange.Value & chars(i).Text
End If
Next i
For i = 1 To chars.Count
With m_targetRange.Characters(i, 1).Font
.Name = chars(i).Name
.FontStyle = chars(i).FontStyle
.Size = chars(i).Size
.Strikethrough = chars(i).Strikethrough
.Superscript = chars(i).Superscript
.Subscript = chars(i).Subscript
.OutlineFont = chars(i).OutlineFont
.Shadow = chars(i).Shadow
.Underline = chars(i).Underline
.Color = chars(i).Color
.TintAndShade = chars(i).TintAndShade
.ThemeFont = chars(i).ThemeFont
End With
Next i
End Sub
How to use it:
Sub test()
Dim target As Range
Dim myChars As MyCharacters
Application.ScreenUpdating = False
Set target = Worksheets("Demo").Range("A1")
Set myChars = New MyCharacters
myChars.Delete targetRange:=target, start:=300, length:=27
Application.ScreenUpdating = True
End Sub
Before:
After:
To make it more stable, you should:
Disable all events while operating
Never call .Activate or .Select
Paste directly in the targeted cell with WorkSheet.Paste
Cancel the Copy operation with Application.CutCopyMode = False
Reuse the same document and not create one for each iteration
Do as less operations as possible in an iteration
Use early binding [New Word.Application] instead of late binding [CreateObject("Word.Application")]
Your example refactored :
Sub FindAndReplace()
Dim dictionary(), target As Range, ws As Worksheet, cell As Range, i As Long
Dim strFind As String, strReplace As String, diffCount As Long, replaceCount As Long
Dim appWord As Word.Application, content As Word.Range, find As Word.find
dictionary = [Sheet1!A1].CurrentRegion.Value
Set target = Cells.SpecialCells(xlCellTypeConstants)
' launch and setup word
Set appWord = New Word.Application
Set content = appWord.Documents.Add().content
Set find = content.find
find.ClearFormatting
find.Font.Bold = False
find.replacement.ClearFormatting
' disable events
Application.Calculation = xlManual
Application.ScreenUpdating = False
Application.EnableEvents = False
' iterate each cell
Set ws = target.Worksheet
For Each cell In target.Cells
' copy the cell to Word and disable the cut
cell.Copy
content.Delete
content.Paste
Application.CutCopyMode = False
' iterate each text to replace
For i = 2 To UBound(dictionary)
If Trim(dictionary(i, 1)) <> Empty Then
replaceCount = 0
strFind = dictionary(i, 1)
strReplace = dictionary(i, 2)
' replace in the document
diffCount = content.Characters.count
find.Execute FindText:=strFind, ReplaceWith:=strReplace, format:=True, Replace:=2
' count number of replacements
diffCount = diffCount - content.Characters.count
If diffCount Then
replaceCount = diffCount \ (Len(strFind) - Len(strReplace))
End If
Debug.Print replaceCount
End If
Next
' copy the text back to Excel
content.Copy
ws.Paste cell
Next
' terminate Word
appWord.Quit False
' restore events
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
How about change it from: activesheet.paste
to:
activesheet.activate
activecell.pastespecial xlpasteAll
This post seems to explain the problem and provide two solutions:
http://www.excelforum.com/excel-programming-vba-macros/376722-runtime-error-1004-paste-method-of-worksheet-class-failed.html
Two items come to light in this post:
Try using Paste Special
Specify the range you wish to paste to.
Another solution would be to extract the targeted cells as XML, replace the text with a regular expression and then write the XML back to the sheet.
While it's much faster than working with Word, it might require some knowledge with regular expressions if the formats were to be handled. Moreover it only works with Excel 2007 and superior.
I've assemble an example that replaces all the occurences with the same style:
Sub FindAndReplace()
Dim area As Range, dictionary(), xml$, i&
Dim matchCount&, replaceCount&, strFind$, strReplace$
' create the regex object
Dim re As Object, match As Object
Set re = CreateObject("VBScript.RegExp")
re.Global = True
re.MultiLine = True
' copy the dictionary to an array with column1=search and column2=replacement
dictionary = [Sheet1!A1].CurrentRegion.Value
'iterate each area
For Each area In ActiveSheet.Cells.SpecialCells(xlCellTypeConstants)
' read the cells as XML
xml = area.Value(xlRangeValueXMLSpreadsheet)
' iterate each text to replace
For i = 2 To UBound(dictionary)
If Trim(dictionary(i, 1)) <> Empty Then
strFind = dictionary(i, 1)
strReplace = dictionary(i, 2)
' set the pattern
re.pattern = "(>[^<]*)" & strFind
' count the number of occurences
matchCount = re.Execute(xml).count
If matchCount Then
' replace each occurence
xml = re.Replace(xml, "$1" & strReplace)
replaceCount = replaceCount + matchCount
End If
End If
Next
' write the XML back to the sheet
area.Value(xlRangeValueXMLSpreadsheet) = xml
Next
' print the number of replacement
Debug.Print replaceCount
End Sub
DDuffy's answer is useful.
I found the code can run normally at slowly cpu PC .
add the bellow code before paste, the problem is sloved:
Application.Wait (Now + TimeValue("0:00:1"))'wait 1s or more
ActiveSheet.Paste

Mirror a single table to multiple sheets in excel using vba

I have one table in the database sheet in which i would want to paste link to another sheet. However i realised that it is not possible using excel and vba. Is there any ways to reference these tables automatically? Equating the cell ranges is one way that i know of but it is extremely tedious because i have over 50 tables of such. Hard coding these equations are a trouble.This is a basic code I have done to copy paste a table .
Sub table()
ActiveSheet.ListObjects("Table1").Range.Copy
'This code will run only when the cursor is at activesheet
Sheets("Sheeet2").Range("A2").PasteSpecial xlPasteValues
End Sub
Here is an example of how to add Table Connections to a new Workbook and a way to Refresh the tables.
The code steps through each ListObject in ListObjects (Tables), .Add's the connection to the new Workbook and places the Table into the Worksheet.
It then creates a new Worksheet and process the next ListObject.
You can change the Workbook and Worksheet names + path to your needs.
*Do note that for unknown reasons to me the Table mixes the rownumbers up when placing them into the new Worksheet, it however doesn't mix the Columns.
AddTableConnectionsToNewWB code:
Sub AddTableConnectionsToNewWB()
Dim tbl As ListObject
Dim tblConn As ListObjects
Dim wb As Workbook
Application.ScreenUpdating = False
Set wb = Workbooks("TableConnections.xlsm")
Set tblConn = Workbooks("TestBook3.xlsm").Worksheets("Sheet2").ListObjects
For Each tbl In tblConn
wb.Connections.Add2 "WorksheetConnection_TestBook3.xlsm!" & tbl, _
"", "WORKSHEET;H:\Projects\TestBook3.xlsm", "TestBook3.xlsm!" & tbl, 7, True, _
False
If wb.Worksheets.Count = 1 Then
With ActiveSheet.ListObjects.Add(SourceType:=4, Source:=ActiveWorkbook. _
Connections("WorksheetConnection_TestBook3.xlsm!" & tbl), Destination:=Range( _
"$A$1")).TableObject
.RowNumbers = False
.PreserveFormatting = True
.RefreshStyle = 1
.AdjustColumnWidth = True
.ListObject.DisplayName = tbl.Name
.Refresh
End With
wb.Worksheets.Add after:=wb.Worksheets(Worksheets.Count)
Else
With ActiveSheet.ListObjects.Add(SourceType:=4, Source:=ActiveWorkbook. _
Connections("WorksheetConnection_TestBook3.xlsm!" & tbl), Destination:=Range( _
"$A$1")).TableObject
.RowNumbers = False
.PreserveFormatting = True
.RefreshStyle = 1
.AdjustColumnWidth = True
.ListObject.DisplayName = tbl.Name
.Refresh
End With
If tblConn.Item(tblConn.Count).Name <> tbl.Name Then
wb.Worksheets.Add after:=wb.Worksheets(Worksheets.Count)
End If
End If
Next
Application.ScreenUpdating = False
End Sub
Refresh code (this can also be done by simply clicking the refresh all button in Table Tools):
Sub RefreshTableConnections()
Dim wb As Workbook
Application.ScreenUpdating = False
Set wb = Workbooks("TableConnections.xlsm")
wb.RefreshAll
Application.ScreenUpdating = True
End Sub

Importing and filtering .CSV files into Excel via VBA

I'm trying to import from a .csv to an Excel spreadsheet several (20) columns of data whilst cleaning up the data as it is imported.
I am new to using VBA to do anything in Excel. My coding experience is limited to a little VB from back in college so I have a grasp of the idea. I'm more than willing to invest time and effort, even buying a few books (any recommendations?).
The .csv file looks like this:
Job:JS_010815_HEASB,Version:2.40,Units:USSurveyFeet,,,,,,,,,,,,,,,,,
PS1457,17262086.61,711051.298,509.153,CONTROL POINT,,,,,,,,,,,,,,,
JS2924,17262069.42,711898.13,505.726,CKP,CKP:POINT ID,PS7431,CKP:NOTES,,,,,,,,,,,,
PS7431,17262069.36,711898.141,505.705,CP,CP:STYLE,PRIM. CONTROL,CP:TYPE,60D NAIL,CP:SIZE,,CP:CONDITION,UNDISTURBED,CP:PROTECTION,OTHER (SEE NOTES),CP:NOTES,,,,
CD7,17262018.81,711181.868,508,PI,,,,,,,,,,,,,,,
CD8,17262889.87,711158.429,510,PI,,,,,,,,,,,,,,,
PS2337,17258986.57,711490.088,506.345,PI,,,,,,,,,,,,,,,
CD5,17262001.04,711782.507,500,PI,,,,,,,,,,,,,,,
JS2925,17261586.74,711741.759,502.677,WELD,WELD:TYPE,MAIN LINE,WELD:XRAY#,BML-901,WELD:JOINT# AHEAD,1708,WELD:JNT HD HEAT#,M75460,WELD:JOINT # BEHIND,1709,WELD:JNT BK HEAT#,M75460,WELD:STATION,716+59,WELD:NOTES
JS2926,17261586.56,711746.613,507.221,NG,NG:REMARKS,4.5 COV,,,,,,,,,,,,,
JS2927,17261628.59,711745.877,502.167,WELD,WELD:TYPE,TIE IN,WELD:XRAY#,BTI-028,WELD:JOINT# AHEAD,1724,WELD:JNT HD HEAT#,M75455,WELD:JOINT # BEHIND,1708,WELD:JNT BK HEAT#,M75460,WELD:STATION,717+01,WELD:NOTES
JS2928,17261670.4,711749.899,501.692,WELD,WELD:TYPE,MAIN LINE,WELD:XRAY#,BML-926,WELD:JOINT# AHEAD,1725,WELD:JNT HD HEAT#,M75455,WELD:JOINT # BEHIND,1724,WELD:JNT BK HEAT#,M75455,WELD:STATION,717+43,WELD:NOTES
The two things I need to do are:
Remove the ":" and whatever precedes it in each cell.
(Minor) I would like to take the info which would be in cell A1 i.e. Job:JS_010815_HEASB, and insert it at the end of each row.
I'd suggest the easiest way to do this is to split it into the individual parts:
Import (not sure if you want to automate it or not, but if you do, I've included instructions.)
Filter the cells, removing the ":"
Copy Cell A1 to end (or move column A, not sure)
Import
Importing is pretty easy, and can be done with something like this:
Sub importCSV(file As String, wsName As String)
Dim connection As String
connection = "TEXT;" + file
With Worksheets(wsName).QueryTables.Add(Connection:=connection, Destination:=Worksheets(wsName).Range("A1"))
.Name = file
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlOverwriteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
' If you were using a file with some other type of delimeter, you'd set this to false and then that one to true
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.Refresh BackgroundQuery:=False
End With
End Sub
Where file is the file (including directory) and wsName is the name of the worksheet you'll be importing to.
Filter
To filter the cells, try this:
Sub filter(wsName As String)
Dim c As Range
For Each c In Worksheets(wsName).usedRange.Cells
c.value = Right(c.value, Len(c.value) - InStr(c.value, ":"))
Next
End Sub
What this does is it loops through each cell in the usedRange for the given worksheet (where wsName is the name of the worksheet) and sets the object c to it. Then we can simply set c.value to whatever new value we want, in our case, everything to the right of any :.
To do this, we use the Right() function which takes a string and an integer for the length and returns that many characters from the right hand side. To work out how many characters we want, we get the length of the entire string with Len(), and subtract from it the number of characters up to and including the : with InStr().
(InStr() returns the position of the character if it's in there, or 0, which means if the character isn't there, we'll be calling Right() with the length of the string, so it'll just return the full input.)
Copy
Not entirely sure what you were going for here. If you were trying to move the entire column, use:
Sub moveColumnToEnd(wsName As String, colNum As Integer)
Dim columnCount As Integer
With Worksheets(wsName)
columnCount = .UsedRange.Columns.Count
.Columns(colNum).Cut
.Columns(columnCount + 1).Insert
End With
End Sub
Where wsName is the name of the work sheet and colNum is the number of the column you want to move (in your case 1). Hopefully the code itself is pretty self explanatory. If not, just ask.
If you were trying to just copy Cell A1, try this:
Sub copyA1ToEnd(wsName As String)
Dim columnCount As Integer
Dim rowCount As Integer
Dim copyRange As Range
Dim c As Range
With Worksheets(wsName)
columnCount = .UsedRange.Columns.Count
rowCount = .UsedRange.Rows.Count
' What we're doing here is getting the range from the first cell of the last column+1
' all the way to the bottom most cell of that column. The Cells() command takes it's
' arguments (row, col) not (X, Y) like you'd probably expect.
Set copyRange = .Range(.Cells(1, columnCount + 1), .Cells(rowCount, columnCount + 1))
' Again, like in the filter function, we loop through each cell in the range and set
' it to what we want it to be
For Each c In copyRange.Cells
c.Value = .Range("A1").Value
Next
End With
End Sub
Where wsName is the name of the worksheet. Again, hopefully it's pretty self explanatory.

Automate Text Import in Excel 2007

I'm trying to write an Excel macro using VBA to automate importing CSV text into a spreadsheet but I've never done it before. I need to make sure that the Text Import Wizard that comes up is run through the same way each time. The steps I need to take are:
Open a file, using an open file dialog
Set type to Delimited
Set Delimiter to comma
Set all columns to be imported as Text
Auto fit all columns
I can't seem to wade through the documentation that shows how to do these things like open files. Even being able to start there would be helpful.
The code below will allow a user to browse for a csv file.
It will then :
Open the selected file, treating the data as text
Resize the columns
Move the data into the workbook from which the code is run.
The .opentext code needs to be updated depending on the number of columns in the source data.
Sub ImportCSV()
Dim vPath As Variant
Dim wb As Excel.Workbook
Dim ws As Excel.Worksheet
Set wb = Excel.ActiveWorkbook
Set ws = Excel.ActiveSheet
vPath = Application.GetOpenFilename("CSV (Comma Delimited) (*.csv),*.csv" _
, 1, "Select a file", , False)
''//Show the file open dialog to allow user to select a CSV file
If vPath = False Then Exit Sub
''//Exit macro if no file selected
Workbooks.OpenText Filename:=vPath, Origin:=xlMSDOS, StartRow:=1 _
, DataType:=xlDelimited, TextQualifier:=xlDoubleQuote, Comma:=True _
, FieldInfo:=Array(Array(1, xlTextFormat), Array(2, xlTextFormat), _
Array(3, xlTextFormat))
''//The fieldinfo array needs to be extended to match your number of columns
Columns.EntireColumn.AutoFit
''//Resize the columns
Sheets(1).Move Before:=wb.Sheets(1)
''//Move the data into the Workbook
End Sub
Public Sub Example()
Const csPath As String = "C:\Test\Example.csv"
Dim ws As Excel.Worksheet
Set ws = Excel.ActiveSheet
With ws.QueryTables.Add("TEXT;" & csPath, ws.Cells(1, 1))
.FieldNames = True
.AdjustColumnWidth = True
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileCommaDelimiter = True
''// This array will need as many entries as there will be columns:
.TextFileColumnDataTypes = Array(xlTextFormat, xlTextFormat)
.Refresh
End With
End Sub
I ended up making some tweaks to the function before putting it into use.
Public Sub OpenCsv()
' I don't expect any more columns than 256 in my environment, so I can
' just fill this array and call it done.
Dim columnFormats(0 To 255) As Integer
For i = 0 To 255
columnFormats(i) = xlTextFormat
Next i
Dim filename As Variant
filename = Application.GetOpenFilename("All Files (*.*),*.*", 1, "Open", "", False)
' If user clicks Cancel, stop.
If (filename = False) Then
Exit Sub
End If
Dim ws As Excel.Worksheet
Application.Workbooks.Add
Set ws = Excel.ActiveSheet
Application.DisplayAlerts = False
Sheets("Sheet2").Delete
Sheets("Sheet3").Delete
Application.DisplayAlerts = True
With ws.QueryTables.Add("TEXT;" & filename, ws.Cells(1, 1))
.FieldNames = True
.AdjustColumnWidth = True
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileCommaDelimiter = True
''// This array will need as many entries as there will be columns:
.TextFileColumnDataTypes = columnFormats
.Refresh
End With
End Sub
Thanks to the above guys for getting me going.