Error 13 when Pasting from another Workbook - vba

I'm new to VBA, and I've been trying to paste some data from one file into my active file. Unfortunately, I've been getting error 13 - Type Mismatch. I've tried changing each of the variable definitions, even declaring them as Variant, but nothing helped. The most relevant part of the code is below, with the error between the asterisks.
dim i, j, k, CompShtStartNum, CompShtQty as integer
dim OldFile as variant
dim WCompWS, WCOl, NumEntryCol, ShtName as string
dim InputsSht as worksheet
dim NumEntryColRange, OldEntryCount as range
'Paste data from Entry Label columns into comparison sheets
'Paste in the data from the old file
For i = CompShtStartNum To CompShtStartNum + CompShtQty - 1
ShtName = ThisWorkbook.Sheets(i).Name
Set OldSht = OldFile.Sheets(ShtName)
Set OldEntryCount = Range(OldSht.Cells(2, 1), OldSht.Cells(Rows.Count, 1).End(xlDown))
For j = 1 To CompShtStartNum - i + 1
For k = 1 To InputsSht.Range(WCol & 12 + j - 1).Value
If OldFile.Sheets(i).Cells(1, k).Value = Sheets(i).Cells(1, k).Value Then
***Sheets(i).Cells(2, k).Resize(OldEntryCount.Rows.Count, 1).Value = Application.Transpose(OldEntryCount.Value)***
End If
Next k
Next j
Next i
For context, here is the full code:
Set OldFile = Application.Workbooks("Old Input File.xlsx")
Let WCompWS = "E"
Let WCol = "F"
Let CompShtStartNum = 2
Set InputsSht = ThisWorkbook.Sheets("Inputs")
Let CompShtQty = InputsSht.Range(WCompWS & 12, InputsSht.Range(WCompWS & 12).End(xlDown)).Count
'Loop thru each sheet and have the user determine the last column of labels. Paste result on Inputs sheet.
For i = CompShtStartNum To CompShtStartNum + CompShtQty - 1
ShtName = ThisWorkbook.Sheets(i).Name
Sheets(ShtName).Activate
NumEntryCol = Application.InputBox("How many columns (from the left-hand side) contain entry labels?" & vbNewLine & "(Examples of entry labels: Library #, Entry #, etc.)" & vbNewLine & vbNewLine & "Please type your answer numerically.", ShtName)
InputsSht.Range(WCol & 12 + i - CompShtStartNum).Value = NumEntryCol
Next i
Set NumEntryColRange = InputsSht.Range(WCol & 12, InputsSht.Range(WCol & 12).End(xlDown))
InputsSht.Activate
'Paste data from Entry Label columns into comparison sheets
'Paste in the data from the old file
For i = CompShtStartNum To CompShtStartNum + CompShtQty - 1
ShtName = ThisWorkbook.Sheets(i).Name
Set OldSht = OldFile.Sheets(ShtName)
Set OldEntryCount = Range(OldSht.Cells(2, 1), OldSht.Cells(Rows.Count, 1).End(xlDown))
For j = 1 To CompShtStartNum - i + 1
For k = 1 To InputsSht.Range(WCol & 12 + j - 1).Value
If OldFile.Sheets(i).Cells(1, k).Value = Sheets(i).Cells(1, k).Value Then
***Sheets(i).Cells(2, k).Resize(OldEntryCount.Rows.Count, 1).Value = Application.Transpose(OldEntryCount.Value)***
End If
Next k
Next j
Next i
Any help or suggestions would be very appreciated!!

However, the result was only the value in A2 being pasted into A2:A7 on the active file sheet. How can I get each of the values in A2:A7 to paste into their respective cells on my active sheet?
Try this
Sheets(i).Cells(2, k).Resize(OldEntryCount.Rows.Count, 1).Value = _
OldEntryCount.Value
Here is a short demonstration. Let's say our worksheet looks like this
Now lets say we want the values of A1:A5 in B1:B5 in Sheet1
Simply try this
Sub Sample()
Dim OldEntryCount As Range
With ThisWorkbook.Sheets("Sheet1")
Set OldEntryCount = .Range("A1:A5")
.Range("B1").Resize(OldEntryCount.Rows.Count, 1).Value = _
OldEntryCount.Value
End With
End Sub
And you will get the result

Related

VBA formula using sheet number instead of sheet name

I am using VBA to write a Macro and it is working exactly as I want, except that I would like my formulas to loop through the sheets instead of using data on 'SAFO-1', 'SAFO-1' refers to the fish Salvelinus fontinalis (SAFO). I have many fish species (e.g., Morone saxatilis (MOSA)) and it would be way more pratical if I could refer to the sheet number instead of their name. Unfortunately, I do not decide sheet names and they have to stay as they are because we're working on shared projects with unique name for every samples. Sheets name change between projects and I want to be able to use my code in all of them. Here is my current code:
Sub Mean()
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim Sheet As Integer
k = 4
i = Application.Sheets.Count
For Sheet = 2 To i
Worksheets(Sheet).Select
j = 3
Do While ActiveCell.Value <> "0"
Range("A" & j).Select
If ActiveCell.Value = "0" Then
Range("A1").Copy
Worksheets("Mean").Range("A" & Sheet + 1).PasteSpecial Paste:=xlPasteValues
Worksheets("Mean").Range("B" & Sheet + 1).Formula = "=(('SAFO-1'!B80)-('SAFO-1'!B75))"
Worksheets("Mean").Range("C" & Sheet + 1).Formula = "=(('SAFO-1'!C80)-('SAFO-1'!C75))"
For k = 4 To 41
Worksheets("Mean").Cells(Sheet + 1, k).FormulaR1C1 = "=AVERAGE('SAFO-1'!R" & j + 10 & "C" & k & ":R" & j - 9 & "C" & k & ")"
Next k
Else
j = j + 1
End If
Loop
Next Sheet
Range("B1:AP2").Copy Worksheets("Mean").Range("A1")
Worksheets("Mean").Select
End Sub
My idea is to replace 'SAFO-1' by 'Sheet1', to be enventually able to write something like :
Worksheets("Mean").Cells(Sheet + 1, k).FormulaR1C1 = "=AVERAGE('Sheet "& Sheet")'!R" & j + 10 & "C" & k & ":R" & j - 9 & "C" & k & ")"
Thanks in advance!
William Fortin
First, we are going to stop using .Select and instead use object handles. I'm not entirely sure where the name of your sheet comes from but I'm going to assume that it's related to the loop and use that as an example. We get an object handle on the sheet using it's number Set currentSheet = Worksheets(Sheet) and then we can grab it's name and use that where we need to in the formula currentSheet.Name.
I hope that even if this code isn't a complete solution that it shows you how to get where you are going.
Option Explicit
Public Sub Mean()
Dim j As Long
Dim k As Long
Dim Sheet As Long
k = 4
For Sheet = 2 To Application.Sheets.Count
Dim currentSheet As Worksheet
Set currentSheet = Worksheets(Sheet)
j = 3
Do
Dim currentCell As Range
Set currentCell = currentSheet.Range("A" & j)
If currentCell.Value = "0" Then
With Worksheets("Mean")
.Range("A" & Sheet + 1).Value = currentSheet.Range("A1").Value
.Range("B" & Sheet + 1).Formula = "=(('" & currentSheet.Name & "'!B80)-('" & currentSheet.Name & "'!B75))"
.Range("C" & Sheet + 1).Formula = "=(('" & currentSheet.Name & "'!C80)-('" & currentSheet.Name & "'!C75))"
For k = 4 To 41
.Cells(Sheet + 1, k).FormulaR1C1 = "=AVERAGE('" & currentSheet.Name & "'!R" & j + 10 & "C" & k & ":R" & j - 9 & "C" & k & ")"
Next k
End With
Else
j = j + 1
End If
Loop While currentCell.Value <> "0"
Next Sheet
currentSheet.Range("B1:AP2").Copy Worksheets("Mean").Range("A1")
Worksheets("Mean").Select
End Sub
We can create an array of worksheet names in VBA and use them to create the formulas we put in the sheets. For example:
Sub useNumber()
sh = Array("big worksheet name", "collosal worksheet name", "mammoth worksheet name", "tiny worksheet name")
Sheets("Sheet1").Range("A1").Formula = "=SUM('" & sh(1) & "'!A3:A6)"
End Sub
If you have many sheets, use a For loop to fill the array rather than the Array() function.
running this creates:
=SUM('collosal worksheet name'!A3:A6)
In Sheet1 cell A1
This approach makes looping over data sheets easier:
Sub useNumberloop()
sh = Array("big worksheet name", "collosal worksheet name", "mammoth worksheet name", "tiny worksheet name")
For i = 1 To 4
Sheets("Sheet1").Range("A" & i).Formula = "=SUM('" & sh(i - 1) & "'!A3:A6)"
Next i
End Sub

Convert headers and row level data to column level

I have very little experience working with VBA, so I'm having a hard time looking up what I am trying to do because I am having a hard time putting what I am trying to do into words.
I have been struggling to write a code to do the below task for the past few days.
Basically what I am trying to do is to convert a set of data to different format.
This what my source data looks like.
Data:
and I need it to look like this
FinalLook:
I've a already setup a code which is lengthy and incomplete.
FIRST PART
I started with retrieving a part of a data (AQ:BA) and then convert to the format in sheet2 with the below code.
Sub FirstPart()
Dim lastRow As Long
Dim Laaastrow As Long
Sheets("sheet2").Range("a2:A5000").ClearContents
lastRow = Sheets("Sheet1").Range("c" & Rows.Count).End(xlUp).Row
Sheets("Sheet2").Range("A2:A" & lastRow).Value = Sheets("Sheet1").Range("c5:c" & lastRow).Value
Sheets("Sheet2").Range("b2:l" & lastRow).Value = Sheets("Sheet1").Range("aq5:ba" & lastRow).Value
End Sub
But.. the problem i am facing with this code is that it pulls all the data, i do not want it to pull all the values, but only the ones which is not empty or 0. In other words, if AQ6:BA6 is empty, script should skip this particular row and go the next one.
SECOND PART (converting the sheet2 data to the final format)
Sub NormalizeSheet()
Dim wsSheet2 As Worksheet
Dim wsSheet4 As Worksheet
Dim strKey As String
Dim clnHeader As Collection
Dim lngColumnCounter As Long
Dim lngRowCounterSheet2 As Long
Dim lngRowCounterSheet4 As Long
Dim rngCurrent As Range
Dim varColumn As Variant
Set wsSheet2 = ThisWorkbook.Worksheets("Sheet2")
Set wsSheet4 = ThisWorkbook.Worksheets("Sheet4")
Set clnHeader = New Collection
wsSheet4.Range("c2:c5000").ClearContents
wsSheet4.Range("e2:e5000").ClearContents
wsSheet4.Range("g2:g5000").ClearContents
lngColumnCounter = 2
lngRowCounterSheet2 = 1
Set rngCurrent = wsSheet2.Cells(lngRowCounterSheet2, lngColumnCounter)
Do Until IsEmpty(rngCurrent.Value)
clnHeader.Add rngCurrent.Value, CStr(lngColumnCounter)
lngColumnCounter = lngColumnCounter + 1
Set rngCurrent = wsSheet2.Cells(lngRowCounterSheet2, lngColumnCounter)
Loop
lngRowCounterSheet2 = 2
lngRowCounterSheet4 = 1
lngColumnCounter = 1
Do While Not IsEmpty(wsSheet2.Cells(lngRowCounterSheet2, lngColumnCounter))
Set rngCurrent = wsSheet2.Cells(lngRowCounterSheet2, lngColumnCounter)
strKey = rngCurrent.Value
lngColumnCounter = 2
Do While Not IsEmpty(wsSheet2.Cells(lngRowCounterSheet2, lngColumnCounter))
Set rngCurrent = wsSheet2.Cells(lngRowCounterSheet2, lngColumnCounter)
If rngCurrent.Value = "NULL" Then
Else
wsSheet4.Range("c" & lngRowCounterSheet4).Offset(1, 0).Value = strKey
wsSheet4.Range("e" & lngRowCounterSheet4).Offset(1, 0).Value = clnHeader(CStr(lngColumnCounter))
wsSheet4.Range("g" & lngRowCounterSheet4).Offset(1, 0).Value = rngCurrent.Value
lngRowCounterSheet4 = lngRowCounterSheet4 + 1
End If
lngColumnCounter = lngColumnCounter + 1
Loop
lngRowCounterSheet2 = lngRowCounterSheet2 + 1
lngColumnCounter = 1
Loop
End Sub
I got this code from another thread posted here on stakcoverflow, i modified a bit to get this work.
The problem i am encountering here is that if Sheet2 B2 is empty, the codes doesnt check sheet C2 instead it skips the whole row, which is not right here.
I know this sounds complicated, and this approach of mine may not be even feasible.
Is there ANY OTHER WAY to do this? Is there any other way to get this in a single shot instead of breaking down the data and move each set of columns to sheet2 then to final format?
See how you get on with this. You'll have to adjust range references, and possibly sheet names
Sub x()
Dim r As Long, c As Range
With Sheet1
For r = 5 To .Range("A" & Rows.Count).End(xlUp).Row
For Each c In .Range(.Cells(r, "AQ"), .Cells(r, "BK")).SpecialCells(xlCellTypeConstants)
If c.Value > 0 Then
Sheet2.Range("A" & Rows.Count).End(xlUp)(2).Value = .Range("B1").Value
Sheet2.Range("B" & Rows.Count).End(xlUp)(2).Value = .Cells(r, 1).Value
Sheet2.Range("C" & Rows.Count).End(xlUp)(2).Value = .Cells(r, 2).Value
Sheet2.Range("D" & Rows.Count).End(xlUp)(2).Value = .Cells(3, c.Column).Value
Sheet2.Range("E" & Rows.Count).End(xlUp)(2).Value = .Cells(4, c.Column).Value
Sheet2.Range("F" & Rows.Count).End(xlUp)(2).Value = "(blank)"
Sheet2.Range("G" & Rows.Count).End(xlUp)(2).Value = c.Value
End If
Next c
Next r
End With
Sheet2.Range("A1").Resize(, 7) = Array("TOPHEADER", "HEADER1", "HEADER2", "FROM", "TO", "TYPE", "UNIT")
End Sub

Loop macro and change ranges with each loop

I’m starting with a worksheet “Med” that has formulas/data/formatting in cells A4:P9. I need to copy those cells to cell A10 (6 rows down). I then need to fill in some of the cells from information in another worksheet “Data”. I need to repeat this the same number of times as the count of Data!(A:A) -1 dropping down 6 rows each time I copy the information.
The data that I need to fill in comes from the Sheet "Data" and moves over one column for each copy in Sheet “Med”.
I have the code to make the first copy, but don’t have any idea where to go from here. Looking at the code below the next copy would go to A16 (6 rows down from A10).
The ranges from the worksheet “Med” would also increase by 6 rows and the columns would stay the same.
The ranges from the worksheet “Data” would move over on column and the row numbers would stay the same.
Jordan
Sub Macro1()
Dim wsData As Worksheet
Dim wsMed As Worksheet
Set wsData = Sheets("Data")
Set wsMed = Sheets("Med")
'Copy data set
wsMed.Range("A4:P9").Copy wsMed.Range("A10") 'Set Premium Values
wsMed.Range("M11").Value = wsData.Range("C20").Value
wsMed.Range("M12").Value = wsData.Range("C21").Value
wsMed.Range("M13").Value = wsData.Range("C22").Value
wsMed.Range("M14").Value = wsData.Range("C23").Value 'Set Assumptions
wsMed.Range("L11").Value = wsData.Range("C24").Value
wsMed.Range("L12").Value = wsData.Range("C25").Value
wsMed.Range("L13").Value = wsData.Range("C26").Value
wsMed.Range("L14").Value = wsData.Range("C27").Value
End Sub
This macro runs the code three times
Sub Macro1()
Dim wsData As Worksheet
Dim wsMed As Worksheet
Set wsData = Sheets("Data")
Set wsMed = Sheets("Med")
Dim i As Integer, j As Integer, x As Integer
i = 10
j = 3
'Copy data set
For x = 1 To 3 ' run 3 times
wsMed.Range("A4:P9").Copy wsMed.Cells(i, 1) 'Set Premium Values
wsMed.Range("M" & i + 1).Value = wsData.Cells(20, j).Value
wsMed.Range("M" & i + 2).Value = wsData.Cells(21, j).Value
wsMed.Range("M" & i + 3).Value = wsData.Cells(22, j).Value
wsMed.Range("M" & i + 4).Value = wsData.Cells(23, j).Value 'Set Assumptions
wsMed.Range("L" & i + 1).Value = wsData.Cells(24, j).Value
wsMed.Range("L" & i + 2).Value = wsData.Cells(25, j).Value
wsMed.Range("L" & i + 3).Value = wsData.Cells(26, j).Value
wsMed.Range("L" & i + 4).Value = wsData.Cells(27, j).Value
i = i + 6
j = j + 1
Next x
End Sub

VBA macro to move cells to a new sheet and removing cell headers in Excel

I am trying to create a VBA macro to move contents on sheet 1 to rows on sheet 2. This is very similar to a question posted on here but I am unable to get the macro to work for me as I am not understanding the variable portion of the answer. Previously Answered Question
We will be pasting a block of info into sheet one that looks like this, with all data in column A across multiple cells:
Issue Description: Testing.
Priority: Standard
Person Number: xxxxxxx
Encounter Number: xxxxxxx
Reported By: John CC X. Smith May 12 2015 11:40AM TSTEST2 (jsmith)
Template Name: fts_clinical_guide_8310
So what we would like is for the information in the Issue Description cell to move to a row on Sheet 2 with the text after the ":" only and so on for the other cells. I also need all of the cell information to stay in 1 row when it gets moved to sheet 2. I hope this makes sense and I would really appreciate any help on this. Thanks.
Edit: Here is the code I am trying to modify. It mentions the original answers "headers" that I would change later. For example it mentions MyID="" and I have no idea how to put info into the quotes to make it work.
Sub MoveOver()
Cells(1, 1).Activate
myId = ""
myTitle = ""
myAuthor = ""
While Not ActiveCell = ""
If UCase(Left(ActiveCell, 4)) Like "*ID*" Then myId = Trim(Mid(ActiveCell, InStr(1, ActiveCell, ":") + 1, Len(ActiveCell)))
If UCase(Left(ActiveCell, 4)) = "TITL" Then myTitle = Trim(Mid(ActiveCell, InStr(1, ActiveCell, ":") + 1, Len(ActiveCell)))
If UCase(Left(ActiveCell, 4)) = "AUTH" Then myAuthor = Trim(Mid(ActiveCell, InStr(1, ActiveCell, ":") + 1, Len(ActiveCell)))
If ActiveCell Like "*---*" Then
'NOW, MOVE TO SHEET2!
toRow = Sheets(2).Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Row
Sheets(2).Cells(toRow, 1) = myId
Sheets(2).Cells(toRow, 2) = myTitle
Sheets(2).Cells(toRow, 3) = myAuthor
myId = ""
myTitle = ""
myAuthor = ""
End If
ActiveCell.Offset(1, 0).Activate
Wend
This will work for you
Sub SpecialCopy()
Dim trg As Worksheet
Set trg = ThisWorkbook.Worksheets(2)
Dim i As Long, j As Long
Dim lastRow As Long: lastRow = Cells(Cells.Rows.Count, 1).End(xlUp).Row
Dim lastRow2 As Long: lastRow2 = trg.Cells(Cells.Rows.Count, 1).End(xlUp).Row + 1
For i = 1 To lastRow ' assuming we starting from second row
trg.Cells(lastRow2, i).Value = Split(Cells(i, 1).Value, ":")(0)
For j = 1 To UBound(Split(Cells(i, 1).Value, ":"))
trg.Cells(lastRow2 + 1, i).Value = trg.Cells(2, i).Value & Split(Cells(i, 1).Value, ":")(j)
Next j
Next i
End Sub
EDIT: I have edited the code, please let me know if this works for you.

Excel VBA: Insert new row in multiple sheets

I have a userform where the user inputs data and then clicks the button Add.
The VBA then creates a new row and inputs the data from the user into that row.
This works fine, however I want to also add a new row in a different sheet as well and this is where I am stuck.
This is my code:
Dim i As String
Dim j As String
Dim k As String
Dim m As String
Dim n As String
j = XIDBox.Value
i = OrgNameBox.Value
k = ContactNameBox.Value
m = PhoneBox.Value
n = EmailBox.Value
dstRw = Sheets("Input Data").Range("A" & Rows.Count).End(xlUp).Row + 1
Sheets("Input Data").Cells(dstRw, 1).Value = i
Sheets("Input Data").Cells(dstRw, 2).Value = j
Sheets("Input Data").Cells(dstRw, 4).Value = k
Sheets("Input Data").Cells(dstRw, 6).Value = m
Sheets("Input Data").Cells(dstRw, 5).Value = n
'Here I want a code that inserts a blank row just as dstRw does above but in a different sheet.
The process is very similar to what you have in place.
'Here I want a code that inserts a blank row just as dstRw does above but in a different sheet.
Dim otherSheet As Worksheet
Set otherSheet = Sheets("Other Sheet Name")
' Insert as the last row.
Dim otherRow As Long
otherRow = otherSheet.Range("A" & Rows.Count).End(xlUp).Row + 1
' Now write the values.
otherSheet.Cells(otherRow, 1).Value = i
otherSheet.Cells(otherRow, 2).Value = j
otherSheet.Cells(otherRow, 4).Value = k
otherSheet.Cells(otherRow, 6).Value = m
otherSheet.Cells(otherRow, 5).Value = n
This works for both sheets using an array for your sheets. You can expand it by adding items to the array in the same manner. You also don't need to store the values as variables, since the name of the object is small, you can just set the cell's values directly from the source.
This finds the last row for each sheet, adds 1 and then sets the values of the cells from your source objects. Then loops the process for the next sheet in the array.
TESTED:
Sub ValueMove()
Dim dstRw As Long
Dim sheet(1) As String
sheet(0) = "Input Data"
sheet(1) = "Different Sheet"
For s = 0 To 1
dstRw = Sheets(sheet(s)).Range("A" & Rows.count).End(xlUp).row + 1
Sheets(sheet(s)).Cells(dstRw, 1).Value = OrgNameBox.Value
Sheets(sheet(s)).Cells(dstRw, 2).Value = XIDBox.Value
Sheets(sheet(s)).Cells(dstRw, 4).Value = ContactNameBox.Value
Sheets(sheet(s)).Cells(dstRw, 6).Value = PhoneBox.Value
Sheets(sheet(s)).Cells(dstRw, 5).Value = EmailBox.Value
Next s
End Sub