I am trying to create a VBA script that copies a cell value when a form control checkbox in the corresponding row is "checked". There are around 116 rows, and I only want to copy the cell value for the checked rows.
For example, my checkboxes are in cells D6:D122. If rows D6, D8, and D10 are checked, I want to copy the values within cells C6, C8, and C10, alphabetize the results and paste them into a newly generated Word document when a command button is clicked. I have figured out how to generate a new word document, but I have trouble copying over the cell values and alphabetizing them.
This is my code as of now:
Sub CommandButton1_click()
Dim wdApp As Word.Application
Dim var as Variant
Set wdApp = New Word.Application
With wdApp
.Visible = True
.Activate
.Documents.Add
End With
End Sub
One of the simpler solutions:
Sub CommandButton1_click()
Dim cl As Range, txt As String
For Each cl In ThisWorkbook.Worksheets(1).Range("D6:D122")
If cl Then txt = txt & vbLf & cl.Offset(0, -1)
Next cl
If Len(txt) > 0 Then ' show Word if you have something to output
Dim wdApp As New Word.Application ' declare and create object at once
With wdApp
.Documents.Add ' the added document automatically becomes active
.Selection.TypeText Mid(txt, 2) 'remove extra (lead) vbLf and output text to Word
.ActiveDocument.Range.Sort
.Visible = True 'show Word after processing to improve performance
End With
Else
MsgBox "There is nothing to output", vbInformation + vbOKOnly
End If
End Sub
Related
I'm designing an excel worksheet, where I can add the text from certain cells to a new word document if a condition for the each cell is met.
My code pastes the text from the cell to the new word document. But it always replaces the text from the previous cell. So only the last cell is visible. How can I change that?
Private Sub CommandButton1_Click()
Dim WrdApp As Word.Application
Dim WrdDoc As Word.Document
Set WrdApp = New Word.Application
WrdApp.Visible = True
WrdApp.Activate
Set WrdDoc = WrdApp.Documents.Add
a = Worksheets("Tabelle1").Cells(Rows.Count, 1).End(xlUp).Row
For i = 6 To a
If Worksheets("Tabelle1").Cells(i, 5).Value = "Ja" Then
Worksheets("Tabelle1").Cells(i, 4).Copy
WrdDoc.Paragraphs(1).Range.PasteSpecial xlPasteValues
End If
Next
Application.CutCopyMode = False
End Sub
Your problem is that you are potentially pasting 6 times into the exact same location, leading to the text at that location being replaced each time. You need to think about what you would do if you were doing this task without code, and then write code that does the same.
You could start by changing:
WrdDoc.Paragraphs(1).Range.PasteSpecial xlPasteValues
to
WrdDoc.Characters.Last.PasteSpecial xlPasteValues
But you will still need to add something between each value you paste.
I am looking to use multiple (5) checkboxes to filter a single column in an excel table. The column to be filtered contains several markers namely
"","r","x","s","t"
Here a picture of the boxes:
My aim is to tick several boxes and include all the columns with said marker. Using straightforward methods results in the previous filter being cleared instead of being "added".
Here a picture of my (now two) tracking columns, one containing the identifier and another hidden converting that too the checkbox captions using ifs statements so #zac's solution works.
I have a looked around a lot and found a thread on MrExcel where some code was provided however I was unable to adapt it to my exact needs. Sadly whichever button I press it keeps defaulting to the blank ("") marker.
Below is my code for a sub that should be called by each checkbox.
Background info:
The identifier value are defined in a table and assigned a dynamic named range "tracking"
The column to be filtered is called ("Project Flag")
The code is contained in a seperate module
Sub Project_Filter()
Dim objcBox As Object
Dim cBox As Variant
Set Dbtbl = Sheets("Database").ListObjects("Entire")
ReDim cBox(0)
Dim trackers() As String
Dim i As Integer
Dim x As Variant
i = -1
For Each x In Range("Tracking").Cells 'reading named range into array
i = i + 1
ReDim Preserve trackers(i) As String
trackers(i) = x.Value
Next x
Application.ScreenUpdating = False
With Sheets("Database")
For Each objcBox In .OLEObjects
If TypeName(objcBox.Object) = "CheckBox" Then 'looking for checkboxes
If objcBox.Object.Value = True Then
cBox(UBound(cBox)) = trackers(i) 'setting cbox array as nth trackers value
i = i + 1
ReDim Preserve cBox(UBound(cBox) + 1)
End If
End If
Next
If IsError(Application.Match((cBox), 0)) Then
MsgBox "Nothing Selected"
Exit Sub
End If
ReDim Preserve cBox(UBound(cBox))
If Not .AutoFilterMode Then
Dbtbl.Range.AutoFilter
Dbtbl.Range.AutoFilter Field:=Dbtbl.HeaderRowRange.Find("Project Flag").Column, Criteria1:=Array(cBox)
End If
End With
Application.ScreenUpdating = True
End Sub
So after some trial and error i found out that the array cbox() only contains the first value of my trackers array, hence it only filtering the blank entries. No idea what causes that but thought it might be noteworthy
Based on our conversation and the picture of your checkboxes in your description, we can get the filter text from the caption:
Option Explicit
Sub Project_Filter()
Dim oOLE As Object
Dim oWS As Worksheet: Set oWS = ThisWorkbook.Worksheets("Sheet1") ' <--- Remeber to change this
Dim aFilter As Variant
Dim sFilterChar As String
' Referenc the sheet
With oWS
' If 'All Projects' checkbox is selected, unselect all other checkboxes
If .OLEObjects("chkAll").Object.Value Then
ClearCheckboxes
End If
' Loop to capture all selected check boxes
For Each oOLE In .OLEObjects
If TypeName(oOLE.Object) = "CheckBox" And oOLE.Object.Value And oOLE.Object.Caption <> "All Projects" Then
If Not IsArray(aFilter) Then
ReDim aFilter(0)
Else
ReDim Preserve aFilter(UBound(aFilter) + 1)
End If
sFilterChar = Mid(oOLE.Object.Caption, 2, 1)
If sFilterChar = "]" Then
aFilter(UBound(aFilter)) = ""
Else
aFilter(UBound(aFilter)) = sFilterChar
End If
End If
Next
' Set the filter based on selection
If IsArray(aFilter) Then
.ListObjects("Table1").Range.AutoFilter field:=2, Criteria1:=aFilter, Operator:=xlFilterValues
Else
.ListObjects("Table1").Range.AutoFilter
End If
End With
' Clear Object
Set oWS = Nothing
End Sub
' Clear all checkboxes other than 'All Projects' checkbox
Private Sub ClearCheckboxes()
Dim oOLE As Object
Dim oWS As Worksheet: Set oWS = ThisWorkbook.Worksheets("Sheet1") ' <--- Remeber to change this
With oWS
' Clear checkboxes
For Each oOLE In .OLEObjects
If TypeName(oOLE.Object) = "CheckBox" And oOLE.Object.Caption <> "All Projects" Then
If oOLE.Object.Value Then
oOLE.Object.Value = False
End If
End If
Next
End With
' Clear object
Set oWS = Nothing
End Sub
NOTE: I have All Projects as a checkbox as well
I am having some issues with some VBA code. What I am trying to do is export code from Excel cells and import them into a Word document in a text field.
Here is the code I have.
Sub test()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
Dim objWord As Object
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
objWord.Documents.Open "C:\Users\Acer Windows 7\Desktop\test.docx"
With objWord.ActiveDocument
.Text1.Value = ws.Range("A1").Value
.Text2.Value = ws.Range("B1").Value
.Text3.Value = ws.Range("C1").Value
End With
End Sub
This code takes static cells and exports them into a Word document. What I need is a link or button on each row that will export that code from said row and put them into the word document.
Example if I click the link/button on row 4 it takes the data from C4, E4, F4
Is this possible? I am not sure how to do so.
If there are many rows it can be a bit cumbersome to add a button for each row. I suggest to only use 1 button that exports the selected row. So you only have to maintain 1 button/sub instead of many.
Cells(Row, Column) can be used here.
Sub test()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
Dim objWord As Object
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
objWord.Documents.Open "C:\Users\Acer Windows 7\Desktop\test.docx"
With objWord.ActiveDocument
.Text1.Value = ws.Cells(Selection.Row, 1).Value
.Text2.Value = ws.Cells(Selection.Row, 2).Value
.Text3.Value = ws.Cells(Selection.Row, 3).Value
End With
End Sub
The code above would always use the row of cell which is selected. So first you select the row that you like to export and then you press the button that runs test().
I need to save the contents of a cell to an xml file named by another cell.
I need to perform this check for every row in the sheet.
Sub FormatRange()
Dim rng As Range
Dim row As Range
Dim cell As Range
Set rng = Range("A1:AG686")
For Each row In rng.Rows
Next row
End Sub
For each row I need to save cell AG to xml file named after cell C in the same row.
I am guessing I can use StreamWriter to write the file. I think the real problem is referencing the cells I need.
Sub FormatRange()
Dim rng As Range
Dim row As Range
Dim cell As Range
Set rng = Range("A2:AG686")
' Declare a FileSystemObject.
Dim fso As FileSystemObject
' Create a FileSystemObject.
Set fso = New FileSystemObject
' Declare a TextStream.
Dim stream As TextStream
' Create a TextStream.
For Each row In rng.Rows
Dim path As String
path = "C:\vba\" & row.Cells(1, 4) & ".xml"
' MsgBox (path + row.Cells(1, 33))
Set stream = fso.CreateTextFile(path, True)
stream.Write row.Cells(1, 33)
Next row
stream.Close
End Sub
Did it! Clustered my way through. Thanks for the suggestions.
Do you have to use VBA? I'm guessing if you know what a StreamWriter is you use C# or another .NET language. If so have a look at EPPlus, you can easily loop through your Excel sheet and use the .NET Framework.
http://epplus.codeplex.com/
Here is my flexible solution with right-click action and file choosing dialog:
Public Sub CellSaver()
Dim cell
For Each cell In Application.Selection.Cells
With Application.FileDialog(msoFileDialogSaveAs)
.Title = "Please select the file to save cell contents"
If .Show Then
With CreateObject("Scripting.FileSystemObject").CreateTextFile(.SelectedItems(1), True)
.Write cell
.Close
End With
End If
End With
Next cell
End Sub
Private Sub Workbook_Open()
With Application.CommandBars("Cell").Controls.Add(Temporary:=True)
.Caption = "Save to file"
.Style = msoButtonCaption
.OnAction = "'CellSaver'"
End With
End Sub
Credits go to:
#JMG's answer here
https://www.extendoffice.com/documents/excel/4375-excel-add-button-macro-to-right-click-menu.html
Can I simultaneously declare and assign a variable in VBA?
Excel VBA Cannot call function with onaction
I want, in Word VBA, to repeat copying content from Excel to Word.
Goal: I have a range in an Excel workbook about 250 cells long in column C that is a list of figure titles. I want to paste those titles into Word, as ‘captions’ (while leaving space to put the figures later, putting a consistent source caption on them, etc.)
I wrote code for one cell. I want to loop down to the next cell and insert a new caption with that new title, until all 250 distinct titles are entered.
Here is the code. I have it running a function, which runs a sub to get the title from one cell.
Sub Macro123()
Selection.InsertCaption Label:="Figure", TitleAutoText:="InsertCaption2", _
Title:=".", Position:=wdCaptionPositionBelow, ExcludeLabel:=0
Selection.TypeText Text:=TitleDrop
Selection.Style = ActiveDocument.Styles("EcoCaption")
Selection.TypeParagraph
Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter
Selection.TypeParagraph
Selection.TypeText Text:="Source: Current study, based off landings data from CDFW."
Selection.Style = ActiveDocument.Styles("EcoSource")
Selection.TypeParagraph
Selection.TypeParagraph
Selection.TypeParagraph
End Sub
-----------
Function TitleDrop()
GetExcelTitles
Selection.PasteAndFormat (wdFormatPlainText)
End Function
-----------------
Sub GetExcelTitles()
Dim ObjXL As Object, xlWkBk
Dim strTitleName As String
On Error Resume Next
Set ObjXL = GetObject(, "Excel.Application")
If Err.Number <> 0 Then
MsgBox "No Excel Files are open (Excel is not running)"
Exit Sub
End If
For Each xlWkBk In ObjXL.Workbooks
If xlWkBk.Name = "130611 Figure Lists.xlsx" Then
xlWkBk.Sheets("Figuresonly").Range("C6").Select
xlWkBk.Sheets("Figuresonly").Range("C6").Copy
Exit For
End If
Next
Set ObjXL = Nothing
End Sub
Try changing some of your code to be like the following and make GetExcelTitles call your Paste Sub, not the other way around.
Dim rng as Range
For Each xlWkBk In ObjXL.Workbooks
If xlWkBk.Name = "130611 Figure Lists.xlsx" Then
For each xlWkBk.Sheets("Figuresonly").Range("C1", "C250")
rng.Select
rng.Copy
Call TitleDrop
Next
End If
Next
Cheers, LC