Macro to extract references out of a word document - macos

I am a researcher where I have to work frequently with research papers containing references in following formats embedded within text
Group 1
(Sajid, 2021); or
(Sajid and Aqeel, 2021); or
(Sajid et al., 2021)
or
Group 2
Sajid (2021); or
Sajid and Aqeel (2021); or
Sajid et al. (2021)
I have a following macro that works well with first group 1 but it does not works with Group 2
Sub ExtractRefsFromSelection()
MsgBox ("This macro extracts references from selected text.")
Dim SearchRange As range, DestinationDoc$, SourceDoc$
DestinationDoc$ = "Refs.doc"
SourceDoc$ = ActiveDocument.Name
Documents.Add DocumentType:=wdNewBlankDocument
ActiveDocument.SaveAs DestinationDoc$, wdFormatDocument
Documents(SourceDoc$).Activate
Set SearchRange = ActiveDocument.range
With SearchRange.Find
.ClearFormatting
.Text = "\([!\)]#[0-9]{4}\)"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
While .Execute
Documents(DestinationDoc$).range.Text = Documents(DestinationDoc$).range.Text + SearchRange.Text
Wend
End With
End Sub
I have tried amending the following line
.Text = "\([!\)]#[0-9]{4}\)"
to
.Text = "[!\)]\(#[0-9]{4}\)"
but it extracts year only like (2021) only but not its authors of citations in Group 2
any help?

If the documents you're working with have used Word's referencing tools, you can replicate the references then insert the full details of each citation, with the author/editor details. For example:
Sub Demo()
Application.ScreenUpdating = False
Dim DocSrc As Document, DocTgt As Document, Fld As Field, i As Long
Set DocSrc = ActiveDocument: Set DocTgt = Documents.Add
With DocSrc
With .Bibliography
For i = 1 To .Sources.Count
DocTgt.Bibliography.Sources.Add .Sources(i).XML
Next
End With
For Each Fld In .Fields
With Fld
If .Type = wdFieldCitation Then
With DocTgt
.Range.InsertAfter vbCr
.Fields.Add .Paragraphs.Last.Range, wdFieldEmpty, Replace(Fld.Code.Text, "\n", ""), False
End With
End If
End With
Next
End With
Application.ScreenUpdating = True
End Sub

Related

vbscript: How to include search text of a Word table in selection ?

I'm using these scripts for a 'search and replace' action in VBscript. Problem is that some of the search fields are in a table in the Word document. My selection doesn't seem to include the text in that table. How can I improve my scripts so that my selection does include that text and replaces in the table as well?
function sendLetterGeneric(letter, Vars1, Vars2)
Set oWord = CreateObject("Word.Application")
oWord.Visible = False
oWord.Documents.Open letter
Set objSelection = oWord.Selection
call replaceText(objSelection, Vars1, Vars2)
oWord.PrintOut
oWord.activedocument.Saved = True
oWord.activedocument.close
oWord.Quit
end function
function replaceText(objSelection, Vars1, Vars2)
Const wdReplaceAll = 2
dim counter
counter = 0
for each var in Vars1
objSelection.Find.Text = Vars1(counter)
objSelection.Find.Forward = TRUE
objSelection.Find.MatchWholeWord = TRUE
objSelection.Find.Replacement.Text = Vars2(counter)
objSelection.Find.Execute ,,,,,,,,,,wdReplaceAll
counter = counter +1
next
end function

Multiple CSVs to single excel VBS

I am trying to read multiple CSVs into single spreadsheet. I got below code from google.
There are 10 CSVs present in "C:\Users\achayapa\Desktop\test". I need to have each of these CSVs in a single excel. could someone please help?
I am new to vb script.
Sub MacroLoop()
Dim strFile As String
Dim ws As Worksheet
strFile = Dir("C:\Users\achayapa\Desktop\test\*.csv")
Do While strFile <> vbNullString
ws = Sheets.Add
With ws.QueryTables.Add(Connection:= _
"TEXT;" & "C:\Users\achayapa\Desktop\test\" & strFile, Destination:=Range("$A$1"))
.Name = strFile
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 437
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh(BackgroundQuery:=False)
End With
strFile = Dir
Loop
End Sub
I just thought of sharing the answer to above question.
Create a VBA script as below:
Sub Macro1()
Dim strPath As String
Dim strFile As String
strPath = "C:\test\"
strFile = Dir(strPath & "*.csv")
Do While strFile <> ""
With ActiveWorkbook.Worksheets.Add
With .QueryTables.Add(Connection:="TEXT;" & strPath & strFile, _
Destination:=.Range("A1"))
.Parent.Name = Replace(strFile, ".csv", "")
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = False
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End With
strFile = Dir
Loop
End Sub
In above code include for path - '\' For example - C:\test\
After this follow include above VBA in Excel, follow steps as in below link:
http://www.ablebits.com/office-addins-blog/2013/12/06/add-run-vba-macro-excel/
Short answer: Yes it is possible.
Step 0 of long answer:
There are 2 syntactical errors in you SWub MacroLoop():
ws = Sheets.Add must be Set ws = Sheets.Add because you want to assign an object to ws.
.Refresh(BackgroundQuery:=False) must be .Refresh BackgroundQuery:=False because you must not use param list () when calling (a function/method as) a Sub (see here).
You may get problems with .TextFilePlatform and .TextFileTrailingMinusNumbers - at least I did when testing on my rather dated Excel. If so, disable those lines (' comment) and try again.
For the next step I would need a detailed account of your testing experience. What result do you expect and how did the actual outcome differ from that?

excel macro search for word and copy sentence

I hope someone can help me with this problem.
I have two documents, one is Word and one is Excel. In the word file I have a list of items, for example:
Title Subtitle
1. Name
Address:
Phone number:
2. Name
Address:
Phone number:
3. Name
Address:
Phone number:
In the excel file I have a list of words in column D. What I want to do is take the word from column D, search for it in the Word document and then copy the sentence from after "Address: " to the ".", put that in Column C (i.e., one cell to the left), and then copy the sentence from after "Phone number: " to the "." and put it in Column B.
One of the parts I can't really wrap my head around is going from the first set of name, address and phone number to the next set.
Can someone help me with the macro on how to do this?
I have thought of expanding it from this:
Sub wordSearch()
' Purpose: display the text between (but not including)
' the words "Title" and "Address" if they both appear.
Dim rng1 As Range
Dim rng2 As Range
Dim strTheText As String
Set rng1 = ActiveDocument.Range
If rng1.Find.Execute(FindText:="Example:") Then
Set rng2 = ActiveDocument.Range(rng1.End, ActiveDocument.Range.End)
If rng2.Find.Execute(FindText:=".") Then
strTheText = ActiveDocument.Range(rng1.End, rng2.Start).Text
MsgBox strTheText
End If
End If
End Sub
As an example, the sub for Excel below gets whole text from catalog.doc located in the same folder as Excel file, parses text with RegExp, loops through contacts and puts it into the Dictionary, then loops through D2:D10 cells and assign appropriate data for matched names to C and B columns respectively. Tested in MS Office 2003, Windows 7 HB.
Option Explicit
Sub GetFromWord()
' Tools - References - add these:
' Microsoft Word 11.0 Object Library
' Microsoft VBScript Regular Expressions 5.5
' Microsoft Scripting Runtime
Dim strCont As String
Dim objCatalog As Scripting.Dictionary
Dim objMatch As IMatch2
Dim objElt As Range
With New Word.Application
.Documents.Open ThisWorkbook.Path & "\catalog.doc"
With .ActiveDocument.Range
.WholeStory
strCont = .Text
End With
.Quit
End With
Set objCatalog = New Scripting.Dictionary
With New RegExp
.Pattern = "\d+\.[ \t]*([^\n\r]*)\s*Address:[ \t]*([^\n\r]*)\s*Phone number:[ \t]*([^\n\r]*)\s*"
.Global = True
.MultiLine = True
.IgnoreCase = True
For Each objMatch In .Execute(strCont)
objCatalog.Add objMatch.SubMatches(0), Array(objMatch.SubMatches(1), objMatch.SubMatches(2))
Next
End With
For Each objElt In Range("D2:D10")
With objElt
If objCatalog.Exists(.Cells(1, 1).Value) Then
.Offset(0, -1) = objCatalog(.Cells(1, 1).Value)(0)
.Offset(0, -2) = objCatalog(.Cells(1, 1).Value)(1)
End If
End With
Next
End Sub
Note, that duplicated contacts in Word will result in error, no additional check implemented.
UPD: In case of any problems with early binding you can use late binding CreateObject(ProgID) as follows, but it isn't a best practice in VBA:
Option Explicit
Sub GetFromWordLBind()
Dim strCont As String
Dim objCatalog, objMatch, objElt As Object
With CreateObject("Word.Application")
.Documents.Open ThisWorkbook.Path & "\catalog.docx"
With .ActiveDocument.Range
.WholeStory
strCont = .Text
End With
.Quit
End With
Set objCatalog = CreateObject("Scripting.Dictionary")
With CreateObject("VBScript.RegExp")
.Pattern = "\d+\.[ \t]*([^\n\r]*)\s*Address:[ \t]*([^\n\r]*)\s*Phone number:[ \t]*([^\n\r]*)\s*"
.Global = True
.MultiLine = True
.IgnoreCase = True
For Each objMatch In .Execute(strCont)
objCatalog.Add objMatch.SubMatches(0), Array(objMatch.SubMatches(1), objMatch.SubMatches(2))
Next
End With
For Each objElt In Range("D2:D10")
With objElt
If objCatalog.Exists(.Cells(1, 1).Value) Then
.Offset(0, -1) = objCatalog(.Cells(1, 1).Value)(0)
.Offset(0, -2) = objCatalog(.Cells(1, 1).Value)(1)
End If
End With
Next
End Sub

Excel VBA - Apply auto filter and Sort by specific colour

I have an auto-filtered range of data. The auto filter was created by the following VB code:
Sub Colour_filter()
Range("A4").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Selection.AutoFilter
End Sub
I would like to sort the values in column "A" (the data actually start from cell "A4") by the following colour ( Color = RGB(255, 102, 204) ) so all the cells with that colour sort to the top.
It would be fab if the extra code could be added to my existing code?
My office is really noisy and my VB isn’t the best. It is doubly hard with laughing, chatting ladies all about. Any help will be stress relief heaven!! (p.s. no poke at the ladies it’s just my office is 95% women).
Edited per request by #ScottHoltzman.
My requested code forms part of a larger code which would confuse matters, although here is a slimmed down version of the aspect I currently need.
Sub Colour_filter()
' Following code( using conditional formatting) adds highlight to 'excluded' courses based
'on 'course code' cell value matching criteria. Courses codes matching criteria are highlighted
'in 'Pink'; as of 19-Nov-2012 the 'excluded' course codes are
'(BIGTEST, BIGFATCAT).
' <====== CONDITIONAL FORMATTING CODE STARTS HERE =======>
Columns("A:A").Select
Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlEqual, _
Formula1:="=""BIGTEST"""
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Interior
.Color = 13395711
End With
Selection.FormatConditions.Add Type:=xlCellValue, Operator:=xlEqual, _
Formula1:="=""BIGFATCAT"""
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Interior
.Color = 13395711
End With
' <====== CONDITIONAL FORMATTING CODE ENDS HERE =======>
' Following code returns column A:A to Font "Tahoma", Size "8"
Columns("A:A").Select
With Selection.Font
.Name = "Tahoma"
.FontStyle = "Regular"
.Size = 8
.ThemeColor = xlThemeColorLight1
.ThemeFont = xlThemeFontNone
End With
With Selection
.HorizontalAlignment = xlLeft
.VerticalAlignment = xlTop
.WrapText = False
End With
' Following code adds border around all contiguous cells ion range, similar to using keyboard short cut "Ctrl + A".
Range("A4").Select
ActiveCell.CurrentRegion.Select
With Selection
Selection.Borders(xlDiagonalDown).LineStyle = xlNone
Selection.Borders(xlDiagonalUp).LineStyle = xlNone
End With
With Selection.Borders(xlEdgeLeft)
.LineStyle = xlContinuous
.ColorIndex = xlAutomatic
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeTop)
.LineStyle = xlContinuous
.ColorIndex = xlAutomatic
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.ColorIndex = xlAutomatic
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeRight)
.LineStyle = xlContinuous
.ColorIndex = xlAutomatic
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlInsideVertical)
.LineStyle = xlContinuous
.ColorIndex = xlAutomatic
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlInsideHorizontal)
.LineStyle = xlContinuous
.ColorIndex = xlAutomatic
.TintAndShade = 0
.Weight = xlThin
End With
' Following code adds 'Blue' cell colour to all headers in Row 4 start in Cell "A4".
Range("A4").Select
Range(Selection, Selection.End(xlToRight)).Select
With Selection
.HorizontalAlignment = xlLeft
.VerticalAlignment = xlTop
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorLight2
.TintAndShade = 0.399975585192419
.PatternTintAndShade = 0
End With
With Selection.Font
.ThemeColor = xlThemeColorDark1
.TintAndShade = 0
End With
Selection.Font.Bold = True
'<== adds auto-filter to my range of cells ===>
Range("A4").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Selection.AutoFilter
End Sub
Well here is a small Sub that does the following sorting as per shown image. Most of the values like dimensions/range sizes are very static since this is a sample. You may improve it to be dynamic. Please comment if this code is going in the right direction so I can update with the final sort.
EDITTED CODE WITH DOUBLE SORT KYES
code:
Option Explicit
Sub sortByColor()
Dim rng As Range
Dim i As Integer
Dim inputArray As Variant, colourSortID As Variant
Dim colourIndex As Long
Set rng = Sheets(1).Range("D2:D13")
colourIndex = Sheets(1).Range("G2").Interior.colorIndex
ReDim inputArray(1 To 12)
ReDim colourSortID(1 To 12)
For i = 1 To 12
inputArray(i) = rng.Cells(i, 1).Interior.colorIndex
If inputArray(i) = colourIndex Then
colourSortID(i) = 1
Else
colourSortID(i) = 0
End If
Next i
'--output the array with colourIndexvalues and sorting key values
Sheets(1).Range("E2").Resize(UBound(inputArray) + 1) = _
Application.Transpose(inputArray)
Sheets(1).Range("F2").Resize(UBound(colourSortID) + 1) = _
Application.Transpose(colourSortID)
'-sort the rows based on the interior colour
Application.DisplayAlerts = False
Set rng = rng.Resize(, 3)
rng.Sort Key1:=Range("F2"), Order1:=xlDescending, _
Key2:=Range("E2"), Order1:=xlAscending, Header:=xlNo, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
Application.DisplayAlerts = True
End Sub
output:

selecting and formating text in richtextbox control vb6

i need to bold some text as i add them to the richtextbox control, currently here is my code
EDIT
With txtDetails
If Not IsNullOrEmpty(title) Then
Dim intStart As Integer
intStart = Len(.Text)
.Text = .Text & title '& vbCrLf
.SelStart = intStart
.SelLength = Len(title)
.SelBold = True
.SelLength = 0
.SelBold = False
.Text = .Text & vbNewLine
End If
If Not IsNullOrEmpty(value) Then
.Text = .Text & value & vbNewLine
End If
.Text = .Text & vbNewLine
End With
can anyone help me with the fix
I have made changes to the code, but still get all the subsequent test i add to be bold, insted of the one am interested in
It looks like you want to append a bolded title if not "missing" and a non-bolded value if it is not "missing."
Option Explicit
Private Function IsNullOrEmpty(ByVal Item As Variant) As Boolean
If IsNull(Item) Then
IsNullOrEmpty = True
ElseIf IsEmpty(Item) Then
IsNullOrEmpty = True
ElseIf VarType(Item) = vbString Then
If Len(Item) = 0 Then
IsNullOrEmpty = True
End If
End If
End Function
Private Sub cmdAppend_Click()
With rtbDisplay
.SelStart = &H7FFFFFFF
If Not IsNullOrEmpty(txtTitle.Text) Then
.SelBold = True
.SelText = txtTitle.Text
txtTitle.Text = ""
.SelBold = False
.SelText = vbNewLine
End If
If Not IsNullOrEmpty(txtValue.Text) Then
.SelText = txtValue.Text
txtValue.Text = ""
.SelText = vbNewLine
End If
End With
txtTitle.SetFocus
End Sub
Here I'm using TextBox controls as the data source but it should give you the general idea. It is often cheaper to use two operations than using String concatenation to add a newline.
Fetching the current .Text and measuring it with Len() is also costly if the contents are large, so just set .SelStart to the maximum value to move to the end.
Setting .Text has some side-effects which prevent your code from doing what you want:
It resets .SelStart so you need to save the length of .Text first.
It resets all of the formatting, so the boldness gets lost.
I'm not into vb but I created a project and tested it out.
Try this
With txtDetails
.SelectionStart = 0
.SelectionLength = txtDetails.TextLength
.SelectionFont = New Font(txtDetails.Font, FontStyle.Bold)
End With

Resources