Excel VBA Course
Excel VBA Course - From Beginner to Expert

200+ Video Lessons
50+ Hours of Video
200+ Excel Guides

Become a master of VBA and Macros in Excel and learn how to automate all of your tasks in Excel with this online course. (No VBA experience required.)

View Course

Copy unprotected cell data vba

0

Hi!

There are two identical files A and B with protected and unprotected cells scattered here and there and the data in A needs to be pasted in B. For a regular cell range e.g. A5:A231, I have been using a code like:

Worksheets("Sheet1").Range("A5:A231").Formula="=[A.xlsm]Sheet1!A5"

but in the second case, the cells are scattered and following this code for each of the cells individually will complicate the process.

Could there be a help from the forum, please?

Answer
Discuss

Discussion

Sure! There could be help. But we need a workbooks to do tests with. None could be more suitable than those that simulate your originals. Please prepare such copies and attach them to your original question. You can do that in Edit mode.
BTW, I wonder why you don't just simply copy the entire sheet. Perhaps, when you show the workbooks, that question will be answered by the circumstances.
Variatus (rep: 4889) Aug 10, '20 at 8:20 pm
Thank you very much for the quick response. I've attatched the file with some explanation.
Asim (rep: 4) Aug 10, '20 at 11:35 pm
Add to Discussion

Answers

0
Selected Answer

The code below should do what you want. Please try it out.

Sub TransferData()
    ' 077

    ' specify first and last cell here
    Const FirstCell As String = "C4"
    Const LastCell  As String = "I8"

    Dim WsS         As Worksheet                ' Source
    Dim WsT         As Worksheet                ' Target
    Dim Arr         As Variant                  ' all Source data
    Dim C           As Long                     ' loop counter: column
    Dim R           As Long                     ' loop counter: row

    ' this sheet is a template, containing locked cell data only
    Set WsT = Worksheets("Sheet2")

    ' this sheet has the data the user filled in already
    Set WsS = Worksheets("Sheet1")

    Application.ScreenUpdating = False          ' saving time
    With WsS
        ' take the date from A1 to the last used cell
        ' using an array should speed up the process
        Arr = Range(.Range("A1"), .Range(LastCell)).Value
        For R = Range(FirstCell).Row To Range(LastCell).Row
            For C = Range(FirstCell).Column To Range(LastCell).Column
                If .Cells(R, C).Locked = False Then
                    WsT.Cells(R, C).Value = Arr(R, C)
                End If
            Next C
        Next R
    End With
    Application.ScreenUpdating = True
End Sub[CODE]Code_Goes_Here
[/code]

Edit 13 Aug 2020   ================================

Here is another version of the above code which allows selection of parts of the source data. You can list as many ranges as you like. In fact, you might list just all the unprotected cells one by one.

Sub TransferData()
    ' 077 13 Aug 2020

    ' specify the range or ranges as CSVs
    Const Sources   As String = "C4:D8,F7,H4:I8"

    Dim WsS         As Worksheet                ' Source
    Dim WsT         As Worksheet                ' Target
    Dim Src         As Range                    ' = Sources
    Dim Sp()        As String                   ' range names from 'Sources'
    Dim Arr         As Variant                  ' WsS data
    Dim Cell        As Range                    ' loop object: cells of Src
    Dim i           As Integer                  ' loop counter: ranges

    ' this sheet is a template, containing locked cell data only
    Set WsT = Worksheets("Sheet2")

    ' this sheet has the data the user filled in already
    Set WsS = Worksheets("Sheet1")

    Application.ScreenUpdating = False          ' saving time
    With WsS
        Arr = Range(.Range("A1"), .UsedRange.SpecialCells(xlCellTypeLastCell)).Value
        Sp = Split(Sources, ",")
        For i = 0 To UBound(Sp)
            Set Src = .Range(Trim(Sp(i)))
            For Each Cell In Src
                With Cell
                    If Not .Locked Then
                        WsT.Cells(.Row, .Column).Value = Arr(.Row, .Column)
                    End If
                End With
            Next Cell
        Next i
    End With
    Application.ScreenUpdating = True
End Sub

On small volumes of data - anything less than a couple of tenthousands of cells is considered small - the difference should be negligible unless your PC runs on a 286 chip. But if you have a slower computer or really large worksheets there is a good chance that you might save the time it took me to write this code within a couple of years, provided you use the procedure frequently :-).

Discuss

Discussion

Thank you very much for your perfect solution. With some changes, the code could call data from another workbook as well. I think the smaller the range, the faster the job, am I right? Or are there other solutions to make it faster?
Asim (rep: 4) Aug 12, '20 at 2:51 am
For 400 x 13 cells speed is unlikely to become a problem. But the slowest parts of the code are to check each cell's Locked status and then write each cell's value individually. Ways could probably be devised to avoid at least one of these two. 
Variatus (rep: 4889) Aug 12, '20 at 8:18 am
Could we break the range as C4:E8, H4:I8, etc. so as to ignore the range in between? My query in this subject matter will stop here. I want to know whether a new thread is to be started for this one.
Asim (rep: 4) Aug 12, '20 at 8:37 am
Once again, I am grateful to you for updating the solution.
Asim (rep: 4) Aug 14, '20 at 3:02 am
Add to Discussion


Answer the Question

You must create an account to use the forum. Create an Account or Login