<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Dealing with payments / transactions and matching reversal entries in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917178#M361283</link>
    <description>&lt;P&gt;This is slightly simpler code than my earlier response.&amp;nbsp; It expects data to be in chronological order within each account, and will retain unmatched debits in the output dataset:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want (drop=i j);
  array history{30} _temporary_;  /*Make large enough for entire history*/
  set have (in=build_history)   have (in=access_history);
  by account;

  /* Initialize history pointer at start of account and start of build_access*/
  if first.account=1 or dif(access_history)=1 then i=0; 
  i+1;
  if first.account then call missing(of history{*});  /*Strictly speaking, this is superfluous*/

  if build_history then do;
    history{i}=ifn(cd='DEBIT',-1*amt,amt);
    if cd='DEBIT' then do j=1 to i-1 until (history{i}=.);
      if history{j}=-1*history{i} then call missing(history{j},history{i});
    end;
  end;
  if access_history=1 and history{i}^=.;  /* Keep the uncancelled transactions*/
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
    <pubDate>Wed, 21 Feb 2024 15:47:57 GMT</pubDate>
    <dc:creator>mkeintz</dc:creator>
    <dc:date>2024-02-21T15:47:57Z</dc:date>
    <item>
      <title>Dealing with payments / transactions and matching reversal entries</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/916984#M361198</link>
      <description>&lt;P&gt;Hi All, I don't think there is a 100% accurate solution here because of the rubbish data I have, so just looking to see if others have come up with any innovative solutions.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Essentially, I have a table which includes both debit &amp;amp; credit transactions and where a payment has been reversed at some point I need to drop both entries from the final output.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The problem I have is there is no way to directly link the debit &amp;amp; credit transactions together. Whilst the amounts will be the same (i.e. +£100 &amp;amp; -£100) they don't always appear on either the same date or on consecutive date for me to be able to group them together and then drop them.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This is an example of how the table is structured and as you will see.... Ref: 001 is cancelled out by Ref: 004 and Ref: 002 is cancelled out by Ref: 007.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;TABLE border="1"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;&lt;P&gt;Transaction Ref&lt;/P&gt;&lt;/TD&gt;&lt;TD&gt;&lt;P&gt;Transaction Date&lt;/P&gt;&lt;/TD&gt;&lt;TD&gt;Account Ref&lt;/TD&gt;&lt;TD&gt;C/D&lt;/TD&gt;&lt;TD&gt;Transaction Amt&lt;/TD&gt;&lt;TD&gt;*Notes (not in table)&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;&lt;P&gt;Ref 1&lt;/P&gt;&lt;/TD&gt;&lt;TD&gt;&lt;P&gt;01/02/2024&lt;/P&gt;&lt;/TD&gt;&lt;TD&gt;Account A&lt;/TD&gt;&lt;TD&gt;CREDIT&lt;/TD&gt;&lt;TD&gt;100&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;Ref 2&amp;nbsp;&lt;/TD&gt;&lt;TD&gt;07/02/2024&lt;/TD&gt;&lt;TD&gt;Account A&lt;/TD&gt;&lt;TD&gt;CREDIT&lt;/TD&gt;&lt;TD&gt;100&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;Ref 3&lt;/TD&gt;&lt;TD&gt;14/02/2024&lt;/TD&gt;&lt;TD&gt;Account A&lt;/TD&gt;&lt;TD&gt;CREDIT&lt;/TD&gt;&lt;TD&gt;50&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;Ref 4&lt;/TD&gt;&lt;TD&gt;15/02/2024&lt;/TD&gt;&lt;TD&gt;Account A&lt;/TD&gt;&lt;TD&gt;DEBIT&lt;/TD&gt;&lt;TD&gt;100&lt;/TD&gt;&lt;TD&gt;*reversal of 01/01/2024&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;Ref 5&lt;/TD&gt;&lt;TD&gt;16/02/2024&lt;/TD&gt;&lt;TD&gt;Account A&lt;/TD&gt;&lt;TD&gt;CREDIT&lt;/TD&gt;&lt;TD&gt;50&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;Ref 6&lt;/TD&gt;&lt;TD&gt;&lt;P&gt;21/02/2024&lt;/P&gt;&lt;/TD&gt;&lt;TD&gt;Account A&lt;/TD&gt;&lt;TD&gt;CREDIT&lt;/TD&gt;&lt;TD&gt;100&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;Ref 7&lt;/TD&gt;&lt;TD&gt;&lt;P&gt;23/02/2024&lt;/P&gt;&lt;/TD&gt;&lt;TD&gt;Account A&lt;/TD&gt;&lt;TD&gt;DEBIT&lt;/TD&gt;&lt;TD&gt;100&lt;/TD&gt;&lt;TD&gt;*reversal of 07/01/2024&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Welcome any expert views/thoughts.&lt;/P&gt;</description>
      <pubDate>Tue, 20 Feb 2024 15:20:36 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/916984#M361198</guid>
      <dc:creator>sasheadache</dc:creator>
      <dc:date>2024-02-20T15:20:36Z</dc:date>
    </item>
    <item>
      <title>Re: Dealing with payments / transactions and matching reversal entries</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917011#M361207</link>
      <description>&lt;P&gt;Your explanatory note for Ref 4&amp;nbsp; (a debit of &lt;SPAN&gt;£&lt;/SPAN&gt;100), says "&lt;SPAN&gt;reversal of 01/01/2024".&amp;nbsp; There is no £100 credit with a date of 01/01/2024.&amp;nbsp; But there are two preceding £100 credits.&amp;nbsp; What rule do you propose to use to find a credit matching the debit, when there are multiple possible matches.&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;And what do you want the output dataset to look like?&amp;nbsp; Same as the output, but with the matches removed?&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Editted addition:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Also do you expect that &lt;U&gt;&lt;EM&gt;&lt;STRONG&gt;every&lt;/STRONG&gt;&lt;/EM&gt;&lt;/U&gt; credit will have a matching debit?&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 20 Feb 2024 18:46:25 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917011#M361207</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2024-02-20T18:46:25Z</dc:date>
    </item>
    <item>
      <title>Re: Dealing with payments / transactions and matching reversal entries</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917077#M361242</link>
      <description>&lt;P&gt;This program removes observations in pairs, namely all DEBITs and earlier matching CREDITs.&amp;nbsp; The oldest possible matching CREDIT is the one that gets removed.&amp;nbsp;&amp;nbsp;Unmatched DEBITs remain in the data set:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
  input ref date :ddmmyy10. account :$1.  cd :$6.  amt;
  format date date9.;
datalines;
1  01/02/2024 A CREDIT 100	 
2  07/02/2024 A CREDIT 100	 
3  14/02/2024 A CREDIT  50	 
4  15/02/2024 A DEBIT  100	*reversal of 01/01/2024
5  16/02/2024 A CREDIT  50	 
6  21/02/2024 A CREDIT 100	 
7  23/02/2024 A DEBIT  100	*reversal of 07/01/2024
run;

data want (drop=i j _:);
 array _history{30} ;         /* Large enough to hold entire history */
 do i=1 by 1 until (last.account);
    set have;
    by account;
    if cd='DEBIT' then amt=-1*amt;      /* Positive for credit, Negative for debit*/
    _history{i}=amt;
    if cd='DEBIT' then do j=1 to i-1 ;  /* Debit?  then review history */
      if _history{j} ^= -1*_history{i} then continue;
      call missing(_history{j},_history{i});
      leave;
    end;
  end;

  do i=1 by 1 until (last.account);
    set have;
    by account;
    if _history{i}^=. then output;
  end;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 21 Feb 2024 03:13:20 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917077#M361242</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2024-02-21T03:13:20Z</dc:date>
    </item>
    <item>
      <title>Re: Dealing with payments / transactions and matching reversal entries</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917086#M361246</link>
      <description>Could you post the output you want to see ?</description>
      <pubDate>Wed, 21 Feb 2024 05:34:42 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917086#M361246</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2024-02-21T05:34:42Z</dc:date>
    </item>
    <item>
      <title>Re: Dealing with payments / transactions and matching reversal entries</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917093#M361252</link>
      <description>Apologies for the typo - the notes should show reversals for transactions dated 01/02 &amp;amp; 07/02 and not January.</description>
      <pubDate>Wed, 21 Feb 2024 07:15:57 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917093#M361252</guid>
      <dc:creator>sasheadache</dc:creator>
      <dc:date>2024-02-21T07:15:57Z</dc:date>
    </item>
    <item>
      <title>Re: Dealing with payments / transactions and matching reversal entries</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917100#M361254</link>
      <description>&lt;TABLE&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;Transaction Ref&lt;/TD&gt;&lt;TD&gt;Transaction Date&lt;/TD&gt;&lt;TD&gt;Account Ref&lt;/TD&gt;&lt;TD&gt;C/D&lt;/TD&gt;&lt;TD&gt;Transaction Amt&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;Ref 3&lt;/TD&gt;&lt;TD&gt;14/02/2024&lt;/TD&gt;&lt;TD&gt;Account A&lt;/TD&gt;&lt;TD&gt;CREDIT&lt;/TD&gt;&lt;TD&gt;50&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;Ref 5&lt;/TD&gt;&lt;TD&gt;16/02/2024&lt;/TD&gt;&lt;TD&gt;Account A&lt;/TD&gt;&lt;TD&gt;CREDIT&lt;/TD&gt;&lt;TD&gt;50&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;Ref 6&lt;/TD&gt;&lt;TD&gt;21/02/2024&lt;/TD&gt;&lt;TD&gt;Account A&lt;/TD&gt;&lt;TD&gt;CREDIT&lt;/TD&gt;&lt;TD&gt;100&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;As you will see transactions 1,2, 4,7 have been dropped because they have cancelled each other out.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 21 Feb 2024 08:01:51 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917100#M361254</guid>
      <dc:creator>sasheadache</dc:creator>
      <dc:date>2024-02-21T08:01:51Z</dc:date>
    </item>
    <item>
      <title>Re: Dealing with payments / transactions and matching reversal entries</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917112#M361256</link>
      <description>&lt;P&gt;Sometime, if you have the data like following,&lt;/P&gt;
&lt;P&gt;What you gonna do with it ?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ksharp_0-1708504358260.png" style="width: 400px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/93963i683C4FCA4BA10575/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Ksharp_0-1708504358260.png" alt="Ksharp_0-1708504358260.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 21 Feb 2024 08:32:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917112#M361256</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2024-02-21T08:32:46Z</dc:date>
    </item>
    <item>
      <title>Re: Dealing with payments / transactions and matching reversal entries</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917113#M361257</link>
      <description>&lt;P&gt;Reversals will never be combined - so in theory the values will always match i.e. Credit £100 &amp;amp; Debit £100.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The main problem is other debits and credits can appear in-between which are not cancelled out. (These are what I want to retain as I am classifying these as true payments)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If you think of how your day to day banking works.... You might buy something today, but then return it and get a refund in 30 days time.&amp;nbsp; I am wanting to drop both transactions from my list, but without a true reference to link them together. (annoying I know)&lt;/P&gt;</description>
      <pubDate>Wed, 21 Feb 2024 08:42:53 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917113#M361257</guid>
      <dc:creator>sasheadache</dc:creator>
      <dc:date>2024-02-21T08:42:53Z</dc:date>
    </item>
    <item>
      <title>Re: Dealing with payments / transactions and matching reversal entries</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917178#M361283</link>
      <description>&lt;P&gt;This is slightly simpler code than my earlier response.&amp;nbsp; It expects data to be in chronological order within each account, and will retain unmatched debits in the output dataset:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want (drop=i j);
  array history{30} _temporary_;  /*Make large enough for entire history*/
  set have (in=build_history)   have (in=access_history);
  by account;

  /* Initialize history pointer at start of account and start of build_access*/
  if first.account=1 or dif(access_history)=1 then i=0; 
  i+1;
  if first.account then call missing(of history{*});  /*Strictly speaking, this is superfluous*/

  if build_history then do;
    history{i}=ifn(cd='DEBIT',-1*amt,amt);
    if cd='DEBIT' then do j=1 to i-1 until (history{i}=.);
      if history{j}=-1*history{i} then call missing(history{j},history{i});
    end;
  end;
  if access_history=1 and history{i}^=.;  /* Keep the uncancelled transactions*/
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 21 Feb 2024 15:47:57 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917178#M361283</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2024-02-21T15:47:57Z</dc:date>
    </item>
    <item>
      <title>Re: Dealing with payments / transactions and matching reversal entries</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917295#M361331</link>
      <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
  input ref date :ddmmyy10. account :$1.  cd :$6.  amt;
  format date date9.;
datalines;
1  01/02/2024 A CREDIT 100	 
2  07/02/2024 A CREDIT 100	 
3  14/02/2024 A CREDIT  50	 
4  15/02/2024 A DEBIT  100	*reversal of 01/01/2024
5  16/02/2024 A CREDIT  50	 
6  21/02/2024 A CREDIT 100	 
7  23/02/2024 A DEBIT  100	*reversal of 07/01/2024
;

data CREDIT(rename=(ref=_ref date=_date account=_account cd=_cd amt=_amt)) DEBIT;
 set have;
 if cd='CREDIT' then output CREDIT;
 if cd='DEBIT' then output DEBIT;
run;

data _null_;
if _n_=1 then do;
 if 0 then set CREDIT;
 declare hash h(dataset:'CREDIT',ordered:'a');
 declare hiter hi('h');
 h.definekey('_date');
 h.definedata('_ref','_date','_account','_cd','_amt');
 h.definedone();
end;
set DEBIT end=last;
do while(hi.next()=0); 
 if amt=_amt and not found then do;found=1;key=_date;rc=hi.next();rc=h.remove(key:key);end;
end;
if last then h.output(dataset:'want');
run;
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Thu, 22 Feb 2024 02:46:16 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/917295#M361331</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2024-02-22T02:46:16Z</dc:date>
    </item>
    <item>
      <title>Re: Dealing with payments / transactions and matching reversal entries</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/968016#M376483</link>
      <description>&lt;P&gt;I’ve seen some folks use fuzzy matching based on amounts and time windows to catch reversed payments, but it’s never perfect.&lt;/P&gt;</description>
      <pubDate>Tue, 03 Jun 2025 11:32:16 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/968016#M376483</guid>
      <dc:creator>Cmrichyy</dc:creator>
      <dc:date>2025-06-03T11:32:16Z</dc:date>
    </item>
    <item>
      <title>Re: Dealing with payments / transactions and matching reversal entries</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/968148#M376506</link>
      <description>&lt;P&gt;I’ve seen some folks use fuzzy matching based on amounts and time windows to catch reversed payments, but it’s never perfect. For smoother payment tracking, I’ve heard good things about Antom’s &lt;A href="https://www.antom.com/checkout-payment/" target="_self"&gt;Secure online checkout&lt;/A&gt;—they’re a leading provider of payment processing services to merchants worldwide and might offer better reconciliation tools to avoid this mess altogether.&lt;/P&gt;</description>
      <pubDate>Wed, 04 Jun 2025 13:08:17 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Dealing-with-payments-transactions-and-matching-reversal-entries/m-p/968148#M376506</guid>
      <dc:creator>Cmrichyy</dc:creator>
      <dc:date>2025-06-04T13:08:17Z</dc:date>
    </item>
  </channel>
</rss>

