skatun
skatun

Reputation: 877

Copy cells in excel with vba

I have a code that reads in the new arrangement of columns from a text file and then rearrange the original columns by copying it in at the correct place, however there is a bug in my code. Instead of copying just 1 column it seems to copy all columns to the right of the column that i want to copy..

so i guess the error is here

'copy the old range
                ws.Range(ws.Cells(Settings.rowHeader + 1, CounterCol), ws.Cells(lrow, CounterCol)).Copy

I want to copy the range AW3:AW80 to A3:A80, but do i need to copy AW:AW to A:A instead? If i do so the stuff in row 1 will be deleted, below is the full code:

    Sub insertColumns()
    Call Settings.init
    Dim i As Integer
    Dim ws As Worksheet
    Dim lrow As Integer
    Dim columNames As Object
    Dim temp As Variant

    'fill dictionary with columnnames from text file
    Set columNames = FileHandling.getTypes(Settings.columnFile)
    Set ws = ActiveWorkbook.Sheets("List")

    'Get max column and row number
    lColumn = HelpFunctions.getLastColumn(ws, Settings.rowHeader)
    lrow = HelpFunctions.getLastRow(ws, HelpFunctions.getColumn("*part*", ws, Settings.rowHeader))


    'Insert all new columns in reverse order from dictionary
    temp = columNames.keys
    For i = columNames.Count - 1 To 0 Step -1
        ws.Columns("A:A").Insert Shift:=xlToRight
        ws.Range("A" & Settings.rowHeader).Value = temp(i)
    Next i

    'last column
    lastColumn = lColumn + columNames.Count

    'we loop through old cells
    CounterCol = columNames.Count + 1
    Do While CounterCol <= lastColumn
        j = 0
        'through each elemnt in dictionary
        For Each element In temp
            j = j + 1
            'compare the old rowheader with any of the rowheader in DICTIONARY
            If UCase(ws.Cells(Settings.rowHeader, CounterCol).Value) = element Then

                'copy the old range
                ws.Range(ws.Cells(Settings.rowHeader + 1, CounterCol), ws.Cells(lrow, CounterCol)).Copy
                'paste it
                ws.Cells(Settings.rowHeader + 1, j).Select
                ws.Paste
                'format the new row
                ws.Cells(Settings.rowHeader + 1, j).EntireColumn.AutoFit


                'Delete the old row
                ws.Columns(CounterCol).EntireColumn.Delete

                'decrease the last column by one since we just deleted the last column
                lastColumn = lastColumn - 1
                found = True
                'Exit For
            End If
        Next element

        'Prompt the user that the old column does not match any of the new column
        If Not found Then
            MsgBox (UCase(ws.Cells(Settings.rowHeader, CounterCol)) & " was not a valid column name please move manually")
        End If

        'reset the found
        found = False

        'go to nect column
        CounterCol = CounterCol + 1
     Loop



End Sub

Below is a screenshot of the dictionary. dictionary

After the first iteration/first copy it should have only copied over the part number column, but as can been seen it has copied over more than just the first column(everything except of drawing number)

enter image description here

Upvotes: 0

Views: 164

Answers (2)

skatun
skatun

Reputation: 877

   'go to nect column
    CounterCol = CounterCol + 1

needed to be deleted. It has to do that the column shifts left when i deleted rows.

Thanks for the help. I hope the code can be used for others who might need to add columns, but still copy over content from old columnsin the right order.

Upvotes: 0

John Coleman
John Coleman

Reputation: 52008

Q: I want to copy the range AW3:AW80 to A3:A80, but do i need to copy AW:AW to A:A instead?

A: No. Any range can be copied.

Rather than trying to debug your code, I'll give you a hint about how to debug such a thing. Lines like

ws.Range(ws.Cells(Settings.rowHeader + 1, CounterCol), ws.Cells(lrow, CounterCol)).Copy

are hard to debug because they are trying to do too much. You have 4 instances of the dot operator and suspected that the problem was with the last one (.Copy). The problem is almost certainly that your code isn't grabbing the range that you think it is grabbing. In other words, one or more of your method invocations earlier in the line needs debugging. In such a situation it is useful to introduce some range variables, set them equal to various values and print their addresses to the immediate window to see what is happening. As an added benefit, having set range variables allows you to use the full power of intellisence in the VBA editor. Something like:

Dim SourceRange As Range, Cell1 As Range, Cell2 As Range
'
'
'
Set Cell1 = ws.Cells(Settings.rowHeader + 1, CounterCol)
Set Cell2 = ws.Cells(lrow, CounterCol)
Set SourceRange = ws.Range(Cell1, Cell2)
Debug.Print Cell1.Address & ", " & Cell2.Address & ", " & SourceRange.Address
'
'Once the above is debugged:
'
SourceRange.Copy 'should work as expected

It is possible that you are copying the range that you want to copy but that your larger program still isn't working. In that case you have some sort of logic error and should be trying to copy some other range. Even then, the above exercise still helps because it makes it clear exactly what your original line was doing.

Upvotes: 1

Related Questions