Need to copy certain data over workbooks - vba

new to VBA here. I've been stuck on this problem for a while now:
Essentially, I need to create a macro that copies over specific data from one sheet to another, that is up to the user to specify. The catch is that while all the data is in one column (B), not all rows of the column have relevant entries; some are blank and some have other data that I don't want.
Only entries that begin with 4 numbers are wanted. I can't seem to get how the iterated copy-pasting works; what I've come up with is as follows:
'defining input
Dim dater As Date
dater = Range("B2")
If dater = False Then
MsgBox "Date not specified"
Exit Sub
End If
Dim sheetin As String
sheetin = Range("B5")
If sheetin = "" Then
MsgBox "Input Sheet not specified"
Exit Sub
End If
Dim wbin As String
wbin = Range("B4")
If wbin = "" Then
MsgBox "Input workbook not specified"
Exit Sub
End If
Dim sheetout As String
sheetout = Range("B9")
If sheetout = "" Then
MsgBox "Output Sheet not specified"
Exit Sub
End If
Dim wbout As String
wbout = Range("B8")
If wbout = "" Then
MsgBox "Output Workbook not specified"
Exit Sub
End If
Windows(wbout).Activate
Dim sh As Worksheet, existx As Boolean
For Each sh In Worksheets
If sh.Name Like sheetout Then existx = True: Exit For
Next
If existx = True Then
If Sheets(sheetout).Visible = False Then Sheets(sheetout).Visible = True
Else
Sheets.Add.Name = CStr(sheetout)
End If
'copy pasting values
Windows(wbin).Activate
Sheets(sheetin).Select
'specify maximum row
iMaxRow = 500
For iRow = 1 To iMaxRow
With Worksheets(sheetin).Cells(iRow, 2)
'Check that cell is not empty.
If .Value = "####*" Then
.Copy Destination:=Workbooks(wbout).Worksheets(sheetout).Range("A" & i)
'Else do nothing.
End If
End With
Next iRow
End Sub
Subsequently i'll have to match data to these entries that have been copied over but I figure once i get the hang of how to do iterated stuff it shouldn't be too much of a problem. But right now i'm really stuck... Please help!

It looks like it should work, except for that part :
With Worksheets(sheetin).Cells(iRow, 2)
If .Value = "####*" Then
.Copy Destination:=Workbooks(wbout).Worksheets(sheetout).Range("A" & i)
End If
End With
The third line contains an unknown variable : i.
You need to define it to contain the number of the line to which you're copying. For example, if you want to copy to the first available line, try this :
Set wsOut = Workbooks(wbout).Worksheets(sheetout)
With Worksheets(sheetin).Cells(iRow, 2)
If .Value = "####*" Then
i = wsOut.Cells(wsOut.Rows.Count, 1).End(xlUp).Row + 1
.Copy Destination:=wsOut.Range("A" & i)
End If
End With

Related

Inserting values from a UserForm to excel sheet which start from a fixed cell?

I have a Cell range Sheets("INVOICE MAKER").Range("D18:D37") (Total 20 Cells), and a little UserForm with name Add Items.
In UserForm there are one Textbox and one Submit Button.
So if I write something in that Textbox and click on Submit Button, Data should be write to next available empty cell in range Sheets("INVOICE MAKER").Range("D18:D37"). And if all 20 cells are filled with data then show a message like "No more rows are available to write data".
Below code don't start writing data from Cell D18, its start writing data from D1.
and doesn't stop after cell D37.
Option Explicit
Dim lRow As Long
Dim ws As Worksheet
Set ws = Worksheets("INVOICE MAKER")
lRow = ws.Cells.Find(What:="*", SearchOrder:=xlRows, _
SearchDirection:=xlPrevious, LookIn:=xlValues).Row + 1
'check for a part number
If Trim(Me.Textbox.Value) = "" Then
Me.Textbox.SetFocus
MsgBox "Please Type Item Name"
Exit Sub
End If
With ws
.Cells(lRow, 5).Value = Me.Textbox.Value
End With
End Sub
Hope below code will help you:
Public Working_Sheet As Worksheet
Public All_Cell_Value As Boolean
Public Write_Cell_No As Integer
Public Content As String
'When button in the form is clicked
Sub Button1_Click()
Write_Content
End Sub
'validation and content writing function
Public Function Write_Content()
All_Cell_Value = True
Set Working_Sheet = Worksheets("Sheet1")
For i = 18 To 37
If Trim(Working_Sheet.Cells(i, "D")) = "" Then
All_Cell_Value = False
Write_Cell_No = i
Exit For
End If
Next i
If All_Cell_Value = False Then
Content = InputBox("Enter the value")
If Content = "" Then
MsgBox ("No Data")
Else
Working_Sheet.Cells(i, "D").Value = Content
End If
Else
MsgBox ("Sorry content is full")
End If
End Function
Maybe this will help!
EDIT #1
Fix some errors, and the code must to be inside a Form, with the TextBox and the Button
EDIT #2
Added a closing statement for the userform or the macro
Option Explicit
Private Sub CommandButton1_Click()
Dim lRow As Long
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("INVOICE MAKER") 'Set from Thisworkbook
ws.Activate 'activate the Invoice Maker
'lRow = ws.Cells.Find(What:="*", SearchOrder:=xlRows, SearchDirection:=xlPrevious, LookIn:=xlValues).Row + 1
Dim iniCell As Integer: iniCell = 18
Dim endCell As Integer: endCell = 37
Dim setCol As Integer: setCol = ws.Range("D1").Column
'As you said, the range is D18:D37, then you can manipulate from this 3 vars
Dim iRange As Range
Dim i As Range
Dim isTheRangeFull As Boolean: isTheRangeFull = False
Dim iMsgbox As Integer
If Trim(Me.TextBox.Value) = "" Then
Me.TextBox.SetFocus
'Ask the user to retry or quit.
iMsgbox = MsgBox("Please Type Item Name" & Chr(10) & "Do you want to retry?", vbYesNo + vbDefaultButton1)
If iMsgbox = 6 Then
GoTo InsertData
'if the user say YES
'do it again
ElseIf iMsgbox = 7 Then
End
'if the user say NO
End If
End If
Set iRange = ws.Range(Cells(iniCell, setCol), Cells(endCell, setCol))
'set your working Range
'This Loop do the job!
For Each i In iRange
isTheRangeFull = True
'if there is no empty cell, won't enter the if, and
'the var continue TRUE, so there is no empty cells...
If i.Value = Empty Then
i.Value = Me.TextBox.Value
isTheRangeFull = False
'the Next line (End) Will close the Form and terminate the macro
'End
'The next line just close the userform
'Unload Me
'Decide which one to uncomment.
Exit For
End If
Next i
If isTheRangeFull Then
MsgBox "No more rows are available to write data"
End
End If
'With ws
' .Cells(lRow, 5).Value = Me.TextBox.Value
'End With
InsertData:
End Sub

VBA - Code is duplicating paste into column not specified in code

I'm using the below code to copy column B in combinedWorkbook to column B in ThisWorkbook but when running the macro it seems to paste column B into column C of ThisWorkbook as well as pasting into column B. I've stepped through the code and it works fine. This seems very strange and would be grataeful with any help on why it's also pasting into column C in ThisWorkbook.
Sub ImportWriteOffs()
Dim filter As String
Dim caption As String
Dim combinedFilename As String
Dim combinedWorkbook As Workbook
' Open BRAM Report Source Data
MsgBox ("Select 'SRMF0035 BRAM Pre Repurchase'")
filter = "Text files (*.*),*.*"
caption = "Select 'SRMF0035 BRAM Pre Repurchase'"
combinedFilename = Application.GetOpenFilename(filter, , caption)
If combinedFilename <> "False" Then
Set combinedWorkbook = Application.Workbooks.Open(combinedFilename)
Else
MsgBox "No file was uploaded", vbExclamation
GoTo LastLine
End If
If combinedWorkbook.Worksheets(1).Range("D7").Value = "Periodic Insurance" Then
' Copy and Paste into working file
Sheets("Tabular Version").Select
Range("B10:B100000").Select
Selection.Copy
ThisWorkbook.Activate
Sheets("Input - Write offs").Select
Range("B10:B100000").Select
ActiveSheet.Paste
Application.CutCopyMode = False
combinedWorkbook.Close False
' Delete last row
ThisWorkbook.Activate
Sheets("Input - Write offs").Select
Range("B10").Select
Selection.End(xlDown).Select
Selection.EntireRow.Delete
Else
MsgBox "Incorrect File Selected"
combinedWorkbook.Close False
Exit Sub
End If
LastLine:
End Sub
You can try this. Notice that you do not need to .Select a cell to copy it. It defeats the purpose of VBA! Just get right to the point: State the range and copy it. No need to select.
Also, no need for GoTo as mentioned by the infamous #ashleedawg, just Exit Sub when needed.
Sub ImportWriteOffs()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Input - Write offs")
Dim filter As String, caption As String, combinedFilename As String
Dim combinedWorkbook As Workbook, ws2 as Worksheet
MsgBox ("Select 'SRMF0035 BRAM Pre Repurchase'")
filter = "Text files (*.*),*.*"
caption = "Select 'SRMF0035 BRAM Pre Repurchase'"
combinedFilename = Application.GetOpenFilename(filter, , caption)
If combinedFilename <> "False" Then
Set combinedWorkbook = Application.Workbooks.Open(combinedFilename)
Set ws2 = combinedWorkbook.Sheets("Tabular Version")
Else
MsgBox "No file was uploaded", vbExclamation
Exit Sub
End If
If combinedWorkbook.Worksheets(1).Range("D7") = "Periodic Insurance" Then
ws2.Range("B10:B" & ws2.Range("B" & ws.Rows.Count).End(xlUp).Row - 1).Copy
ws.Range("B10").PasteSpecial xlPasteValues
ws.Range("B10").PasteSpecial xlPasteFormats
combinedWorkbook.Close False
Else
MsgBox "Incorrect File Selected"
combinedWorkbook.Close False
End If
End Sub
This is happening because the select is actually using a relative reference. But it would be clearer what you want to do if you used Cells instead:
For r = 10 to 10000
ActiveWorkbook.Worksheets("Input - Write-offs").Cells(r, 2) = combinedWorkbook.Worksheets("Tabular Version").Cells(r, 2)
Next
You can implement something similar for deleting the last row, if you are so inclined.

Run-Time Error 91: Can't run through the second line

Here is part of the code I am working on which is a part of a macro.
This is also the same on another file which is basically the same also.
The macro works on the other file while on the other, it doesn't and comes with the Run-time error '91'.
Attached is the code:
shtData.Activate
Dim r As Integer
Dim strassured As String
r = 1
While ActiveSheet.Cells(r, 1) <> ""
ActiveSheet.Cells(r, 1).Select
strassured = ActiveCell.Value
If shtWorkSpace.Range("B3").Value = strassured Then
If shtWorkSpace.Range("A60").Value = "Pending" Then
DataHandling.OverwriteDataTab (strassured)
Exit Sub
Else
MsgBox "This assured name is already in the database. Assured Names must be unique!", vbCritical
shtWorkSpace.Activate
ActiveSheet.Range("A1").Select
Exit Sub
End If
Else
r = r + 1
End If
Wend
I've added an answer, not to provide how to define and Set both worksheets (shtData and shtWorkSpace).
But also to provide a better coding practice, there is no need to Activate worksheets, or use Select and ActiveCell. Instead use fully qualified Ranges and Worksheets.
Code
Sub Test()
Dim shtData As Worksheet
Dim shtWorkSpace As Worksheet
Dim r As Integer
Dim strassured As String
Set shtData = Worksheets("Data") '<-- modify "Data" to your sheet name
Set shtWorkSpace = Worksheets("Workspace") '<-- modify "Workspace" to your sheet name
r = 1
While shtData.Cells(r, 1) <> ""
strassured = shtData.Cells(r, 1).Value
If shtWorkSpace.Range("B3").Value = strassured Then
If shtWorkSpace.Range("A60").Value = "Pending" Then
DataHandling.OverwriteDataTab (strassured)
Exit Sub
Else
MsgBox "This assured name is already in the database. Assured Names must be unique!", vbCritical
shtWorkSpace.Activate
ActiveSheet.Range("A1").Select '<-- not sure why you need to select the sheet and Range("A1")
Exit Sub
End If
Else
r = r + 1
End If
Wend
End Sub

Setting Cells or Ranges to Blank on different worksheets through VBA code

I am having difficulty setting Ranges and cells to a blank value on different worksheets, UNLESS the worksheet is visible.
The code is as follows:
Sub Clean_Up_Ranges()
Dim nm As Worksheet
On Error Resume Next
For Each nm In Worksheets
Worksheets("nm").Select
Range("d7:d37") = ""
Range("k7:k37") = ""
Range("L40:l42") = ""
'..... plenty more ranges
Range("h80:j179") = ""
Calculate
Debug.Print nm.Name
Next
On Error GoTo 0
End Sub
Any ideas appreciated.
Explicitly reference the sheet.
Sub Clean_Up_Ranges()
Dim nm As Worksheet
On Error Resume Next
For Each nm In Worksheets
'Worksheets("nm").Select
nm.Range("d7:d37") = ""
nm.Range("k7:k37") = ""
nm.Range("L40:l42") = ""
'..... plenty more ranges
nm.Range("h80:j179") = ""
Calculate
Debug.Print nm.Name
Next
On Error GoTo 0
End Sub
You can use Activate keyword in your code which will activate the sheet.
See This to know difference between SHEETS.SELECT or SHEETS.ACTIVATE.
Sub Clean_Up_Ranges()
Dim nm As Worksheet
On Error Resume Next
For Each nm In Worksheets
nm.Activate 'Activate the sheet
Range("d7:d37") = ""
Range("k7:k37") = ""
Range("L40:l42") = ""
'..... plenty more ranges
Range("h80:j179") = ""
Calculate
Debug.Print nm.Name
Next
On Error GoTo 0
End Sub

Choose from Excel dropdown programmatically

I want to write a macro that will pick a particular value (in my case, stored in cell A1) from a dropdown list (in my case, in cell D6).
Here's what I have so far:
sr_par2 = Array ("TEXT", 'TEXT2", "TEXT3")
sr = Range("A1").Value
(...)
Dim i As Integer
i = 0
Range("D6").Select
Do While (sr <> ActiveCell.FormulaR1C1)
Range("D6").Select
ActiveCell.FormulaR1C1 = sr_par2(i)
i = i + 1
Loop
Is this what you are trying? I have commented the code so that you will not have a problem understanding it. Still if you do then simply ask :)
Sub Sample()
Dim ws As Worksheet
Dim rngIn As Range, rngOut As Range
Dim MyAr
Dim sFormula As String
Dim i As Long
'~~> Replace this with the relevant worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
'~~> Set your input and output range here
Set rngIn = .Range("A1")
Set rngOut = .Range("D6")
'~~> Get the validation list if there is one
On Error Resume Next
sFormula = rngOut.Validation.Formula1
On Error GoTo 0
If sFormula = "" Then
'~~> If no validation list then directly populate the value
rngOut.Value = rngIn.Value
Else
'validation list TEXT1,TEXT2,TEXT3
MyAr = Split(sFormula, ",")
'~~> Loop through the list and compare
For i = LBound(MyAr) To UBound(MyAr)
If UCase(Trim(rngIn.Value)) = UCase(Trim(MyAr(i))) Then
rngOut.Value = MyAr(i)
Exit For
End If
Next i
'~~> Check if the cell is still blank. If it is then it means that
'~~> Cell A1 has a value which is not part of the list
If Len(Trim(rngOut.Value)) = 0 Then
MsgBox "The value in " & rngOut.Address & _
" cannot be set as the value you are copying is not part of the list"
End If
End If
End With
End Sub
If I understood correctly, this should do what you want :
sr_par2 = Array("TEXT", "TEXT2", "TEXT3")
sr = Range("A1").Value
Dim i As Integer
i = 0
On Error GoTo Handler
Do While (sr <> sr_par2(i))
i = i + 1
Loop
Range("D6").FormulaR1C1 = sr_par2(i)
Exit Sub
Handler:
MsgBox "Value not in the list", vbCritical + vbOKOnly, "Value not found"